Передача целочисленных списков в python

Я хочу передать 2 списка целых чисел в качестве ввода в программу python.

Например, (из командной строки)

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

Целые числа в этом списке могут варьироваться от 1 до 50, список 2 - подмножество List1.
Любая помощь/предложения? Является ли argparse правильным модулем? Любые проблемы при использовании этого?

Я пробовал:

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)

Ответ 1

Вы можете передать их как строки, чем конвертировать в списки. Вы можете использовать argparse или 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']

Пример: python prog.py --l1=1,2,3,4

Кроме того, в качестве строки вы можете передать что-то вроде этого 1-50, а затем разделить на '-' и построить диапазон. Что-то вроде этого:

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

Пример: python prog.py --l1=1-50

Логика Я думаю, вы можете написать себе.:)

Ответ 2

argparse поддерживает параметр nargs, в котором указывается, сколько параметров он ест. Когда nargs="+" принимает один или несколько параметров, вы можете передать -b 1 2 3 4, и он будет назначен как список аргументов b

# 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
# ...

Итак, вы можете запустить:

$ 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]

И это действительно:

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

Ответ 3

Это сработало для меня:

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

Ответ 4

Способ, которым optparse и argparse работа - это чтение аргументов из командной строки, аргументы разделяются пробелом, поэтому, если вы хотите ввести свой список целых чисел через интерфакт командной строки из optparse или argparse - вы можете сделать это, удалив пробелы или окружив свой аргумент ", пример:

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

или

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

Затем ваш script должен преобразовать эти входы в фактический список.

Использование argparse синтаксис (очень похож на 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(',')]

Другой способ сделать это - либо импортировать модуль, который вы хотите запустить, так и передать объекты списка классу, который имеет дело с вашим кодом, или с помощью цикла while и raw_input/input, чтобы собрать нужный список.

Ответ 5

Если единственными аргументами являются списки и разделители, вы можете сделать это относительно просто:

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:]]

Добавление проверки легко:

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.'

Создание справочного сообщения:

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