Передача целочисленных списков в 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]"