2013-03-17 14 views
13

Chcę przekazać 2 listy liczb całkowitych jako dane wejściowe do programu Pythona.Przekazywanie list całkowitych do pytona

Na przykład, (z linii polecenia)

python test.py --a 1 2 3 4 5 -b 1 2 

Liczby na tej liście może być w zakresie od 1-50, 2 Lista jest podzbiorem List1.
Każda pomoc/sugestie? Czy odpowiedni moduł to argparse? Jakiekolwiek obawy w używaniu tego?

Próbowałem:

import argparse 
if __name__ == '__main__': 
    parser = argparse.ArgumentParser() 
    parser.add_argument('--a', help='Enter list 1 ') 
    parser.add_argument('--b', help='Enter list 2 ') 
    args = parser.parse_args() 
    print (args.a) 
+0

Jak wygląda lista liczb całkowitych? – ATOzTOA

+0

Wyświetl przykładową linię poleceń, której zamierzasz użyć? Dodaj także częste komentarze jako część pytania. – ATOzTOA

+0

liczby całkowite z każdej listy mieszczą się w zakresie od 1 do 50. Lista 2 jest podzbiorem listy1 – Swati

Odpowiedz

8

można przekazać je jako ciągi niż konwersji na listach. Można użyć argparse lub optparse.

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('--l1', type=str) 
parser.add_argument('--l2', type=str) 
args = parser.parse_args() 
l1_list = args.l1.split(',') # ['1','2','3','4'] 

Przykład: python prog.py --l1=1,2,3,4

Również jako linię można przekazać coś takiego 1-50, a następnie podzielić na '-' i skonstruować zakres. coś takiego:

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('--l1', type=str, help="two numbers separated by a hyphen") 
parser.add_argument('--l2', type=str) 
args = parser.parse_args() 
l1_list_range = xrange(*args.l1.split('-')) # xrange(1,50) 
for i in l1_list_range: 
    print i 

Przykład: python prog.py --l1=1-50

Logic myślę, że można napisać samemu. :)

+1

Jakiś przykładowy kod do tego? Chcę również podać błąd, jeśli jakaś lista jest pusta lub zawiera numer poza zakresem? – Swati

+0

Prosimy o przyniesienie przykładowej listy, którą chcesz przekazać. –

+1

@Swati StackOverflow nie jest usługą pisania kodu. Spróbuj samodzielnie rozwiązać problem, a następnie poproś o pomoc w rozwiązaniu problemu. –

1

Sposób, że optparse i argparse prace czytają argumenty z linii poleceń, argumenty są podzielone przez white-space, więc jeśli chcesz wprowadzić listę liczb całkowitych poprzez interfact wiersza poleceń z optparse lub argparse - można to zrobić poprzez usunięcie spacji lub otaczając swoją argumentację z ", przykład:

> my_script.py --a "1 2 3 4 5" --b "1 2" 

czyli

> my_script.py --a 1,2,3,4,5 --b 1,2 

Twój sc ript następnie musi przekształcić te dane wejściowe w rzeczywistą listę.

Korzystanie argparse składni (bardzo podobny do optparse):

# with spaces and " 
a_lst = [i for i in args.a.split(' ')] 
b_lst = [i for i in args.b.split(' ')] 

# without spaces and , 
a_lst = [i for i in args.a.split(',')] 
b_lst = [i for i in args.b.split(',')] 

Innym sposobem na to byłoby albo poprzez importowanie modułu, który chcesz uruchomić i przekazując listę obiektów do klasy tej oferty za pomocą kodu lub za pomocą pętli while i raw_input/input, aby zebrać żądaną listę.

1

Jeśli tylko argumenty są wykazy oraz separatory, można to zrobić stosunkowo prosto:

sa = sys.argv.index('-a') 
sb = sys.argv.index('-b') 
lista = [int(i) for i in sys.argv[sa+1:sb]] 
listb = [int(i) for i in sys.argv[sb+1:]] 

Dodawanie walidacja jest proste:

aval = [i for i in lista if i>1 and i<50] 
if len(aval) < len(lista): 
    print 'The -a list contains invalid numbers.' 
bval = [i for i in listb if i>1 and i<50] 
if len(bval) < len(listb): 
    print 'The -b list contains invalid numbers.' 

Wyprodukowanie komunikat pomocy:

if sys.argv[1] in ['-h', '-H'] or len(sys.argv) == 1: 
    print "Usage: <name> -a [list of integers] -b [list of integers]" 
+0

Podoba mi się twoje podejście, w jaki sposób mogę zapewnić pomoc dotyczącą parametrów wejściowych i jakiejkolwiek walidacji dotyczącej zakresu? – Swati

28

argparse obsługuje nargs parametr, który informuje, ile parametrów je. Kiedy nargs="+" przyjmuje jeden lub więcej parametrów, więc można przekazać -b 1 2 3 4 i zostanie on przydzielony w postaci listy do b argumentu

# args.py 
import argparse 

p = argparse.ArgumentParser() 

# accept two lists of arguments 
# like -a 1 2 3 4 -b 1 2 3 
p.add_argument('-a', nargs="+", type=int) 
p.add_argument('-b', nargs="+", type=int) 
args = p.parse_args() 

# check if input is valid 
set_a = set(args.a) 
set_b = set(args.b) 

# check if "a" is in proper range. 
if len(set_a - set(range(1, 51))) > 0: # can use also min(a)>=1 and max(a)<=50 
    raise Exception("set a not in range [1,50]") 

# check if "b" is in "a" 
if len(set_b - set_a) > 0: 
    raise Exception("set b not entirely in set a") 

# you could even skip len(...) and leave just operations on sets 
# ... 

Więc można uruchomić:

$ python arg.py -a 1 2 3 4 -b 2 20 
Exception: set b not entirely in set a 

$ python arg.py -a 1 2 3 4 60 -b 2 
Exception: set a not in range [1,50] 

I to jest ważne:

$ python arg.py -a 1 2 3 4 -b 2 3 
+0

dobra decyzja! prawda, jeśli konieczne jest podanie 50 numerów, a nie 5, to jest długie)) –

+0

Dlaczego użyłeś zestawu? – Swati

+0

Ponieważ to o co prosisz * to * sprawdzenie. Gdy sprawdzisz, czy B jest w A, * to ustawiona operacja * - sprawdź, czy ustawiona jest b - zestaw a jest pusty. Dla zakresów mogłem użyć 'min (a)> = 1 i max (a) <= 50', chociaż chciałem być konsekwentny. Pytałeś o "Lista 2 to podzbiór List1.", Nie? –

3

Ten pracował dla mnie:

parser.add_argument('-i', '--ids', help="A comma separated list IDs", type=lambda x: x.split(','))