web-dev-qa-db-fra.com

Passer des listes d'entiers au python

Je veux passer 2 listes d'entiers en entrée d'un programme python.

Par exemple, (à partir de la ligne de commande)

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

Les nombres entiers dans cette liste peuvent aller de 1 à 50, la liste 2 étant un sous-ensemble de List1.
Avez-vous de l'aide/des suggestions? Est-ce que argparse est le bon module? Des préoccupations en utilisant cela?

J'ai essayé :

import argparse
if __== '__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)
14
Swati

Vous pouvez les transmettre sous forme de chaînes que de convertir en listes. Vous pouvez utiliser argparse ou 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']

Exemple: python prog.py --l1=1,2,3,4

En outre, en tant que ligne, vous pouvez passer quelque chose comme ceci 1-50, puis vous séparer de "-" et construire une plage. Quelque chose comme ça:

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

Exemple: python prog.py --l1=1-50

Je pense que vous pouvez écrire vous-même. :)

7
Ellochka Cannibal

argparse supporte nargs paramètre, qui vous indique le nombre de paramètres qu’il mange. Lorsque nargs="+" il accepte un ou plusieurs paramètres, vous pouvez donc passer -b 1 2 3 4 et il sera affecté en tant que liste à l'argument 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
# ...

Pour que vous puissiez courir:

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

Et ceci est valable:

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

Cela a fonctionné pour moi:

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

MODIFIER:

Je viens de me rendre compte que cela ne répond pas vraiment à la question posée. Jakub a la bonne solution.

4
bobtheterrible

La manière dont optparse et argparse work est qu'ils lisent les arguments à partir de la ligne de commande, les arguments étant divisés par un espace, si vous voulez entrer votre liste d'entiers via la ligne de commande, utilisez optparse ou argparse - vous pouvez le faire en supprimant les espaces ou en entourant votre argument avec ", exemple:

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

ou:

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

Votre script doit ensuite convertir ces entrées en une liste réelle.

Utilisation de argparse syntax (très similaire pour 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(',')]

Une autre façon de procéder consiste à importer le module que vous souhaitez exécuter et à transmettre les objets de liste à une classe qui traite votre code, ou à l'aide d'une boucle while et raw_input / input à collecter. la liste souhaitée.

1
Inbar Rose

Si les arguments seulement sont les listes et les séparateurs, vous pouvez le faire relativement simplement:

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

Ajouter une validation est facile:

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

Produire un message d'aide:

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

Juste en ajoutant celui-ci pour la complétude. J'ai été surpris de ne pas voir cette approche.

from argparse import Action, ArgumentParser


class CommaSeparatedListAction(Action):
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, values.split(','))


parser = ArgumentParser()
parser.add_argument('-l', action=CommaSeparatedListAction)
print(parser.parse_args('-l a,b,c,d'.split()))

# Namespace(l=['a', 'b', 'c', 'd'])

Ceci n’est qu’un exemple élémentaire, mais vous pouvez également ajouter une validation ou transformer des valeurs, telles que les forcer en majuscules.

from argparse import Action, ArgumentParser


class UppercaseLetterCommaSeparatedListAction(Action):
    def __call__(self, parser, namespace, values, option_string=None):
        letters = values.split(',')
        for l in letters:
            self._validate_letter(parser, l)
        setattr(
            namespace,
            self.dest,
            list(map(lambda v: v.upper(), letters))
        )

    def _validate_letter(self, parser, letter):
        if len(letter) > 1 or not letter.isalpha():
            parser.error('l must be a comma separated list of letters')


parser = ArgumentParser()
parser.add_argument('-l', action=UppercaseLetterCommaSeparatedListAction)
print(parser.parse_args('-l a,b,c,d'.split()))

# Namespace(l=['A', 'B', 'C', 'D'])

parser = ArgumentParser()
parser.add_argument('-l', action=UppercaseLetterCommaSeparatedListAction)
print(parser.parse_args('-l a,bb,c,d'.split()))

# usage: list.py [-h] [-l L]
# list.py: error: l must be a comma separated list of letters

parser = ArgumentParser()
parser.add_argument('-l', action=UppercaseLetterCommaSeparatedListAction)
print(parser.parse_args('-l a,1,c,d'.split()))

# usage: list.py [-h] [-l L]
# list.py: error: l must be a comma separated list of letters
0
Allie Fitter