it-swarm.com.de

Übergabe von Integer-Listen an Python

Ich möchte 2 Listen von Ganzzahlen als Eingabe für ein Python-Programm übergeben.

Zum Beispiel (von der Kommandozeile)

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

Die Ganzzahlen in dieser Liste können zwischen 1 und 50 liegen. Liste 2 ist eine Teilmenge von Liste1.
Irgendwelche Hilfe/Vorschläge? Ist argparse das richtige Modul? Haben Sie Bedenken, das zu nutzen?

Ich habe versucht :

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

Sie können sie als Zeichenfolgen übergeben und dann in Listen konvertieren. Sie können argparse oder optparse verwenden.

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

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

Außerdem können Sie als Linie so etwas wie 1-50 übergeben und dann auf '-' aufteilen und den Bereich konstruieren. Etwas wie das:

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

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

Logik Ich denke, Sie können sich selbst schreiben. :)

7

argparse unterstützt nargs parameter und gibt an, wie viele Parameter verwendet werden. Wenn nargs="+" einen oder mehrere Parameter akzeptiert, können Sie -b 1 2 3 4 übergeben, und es wird dem Argument b als Liste zugewiesen

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

So können Sie laufen:

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

Und das ist gültig:

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

Das hat bei mir funktioniert:

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

BEARBEITEN:

Ich habe gerade festgestellt, dass dies die gestellte Frage nicht beantwortet. Jakub hat die richtige Lösung.

4
bobtheterrible

Die Art und Weise, wie optparse und argparse arbeiten, ist, dass sie Argumente aus der Befehlszeile lesen. Argumente werden durch Leerzeichen getrennt. Wenn Sie also Ihre Liste von Ganzzahlen über die Befehlszeile eingeben möchten, interagieren Sie von optparse oder argparse - Sie können dies tun, indem Sie die Leerzeichen entfernen oder Ihr Argument mit " umgeben, Beispiel:

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

oder:

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

Ihr Skript muss diese Eingaben dann in eine tatsächliche Liste konvertieren.

Verwenden von argparse -Syntax (sehr ähnlich für 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(',')]

Eine andere Möglichkeit besteht darin, das Modul, das Sie ausführen möchten, zu importieren und die Listenobjekte an eine Klasse zu übergeben, die sich mit Ihrem Code befasst, oder eine while-Schleife und raw_input / input zum Sammeln zu verwenden die gewünschte Liste.

1
Inbar Rose

Wenn die only - Argumente die Listen und die Trennzeichen sind, können Sie dies relativ einfach tun:

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

Das Hinzufügen einer Validierung ist ganz einfach:

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

Erstellen einer Hilfemeldung:

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

Der Vollständigkeit halber nur dieses hinzufügen. Ich war überrascht, dass ich diesen Ansatz nicht sah.

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'])

Dies ist nur ein einfaches Beispiel, aber Sie können auch Validierungs- oder Transformationswerte hinzufügen, z. B. in Großbuchstaben umwandeln.

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