web-dev-qa-db-ja.com

整数リストをpythonに渡す

pythonプログラムへの入力として整数の2つのリストを渡したいのですが。

たとえば、(コマンドラインから)

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

このリストの整数の範囲は1〜50で、リスト2はリスト1のサブセットです。
ヘルプ/提案はありますか? 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)
16
Swati

リストに変換するよりも、文字列として渡すことができます。 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

ロジック自分で書けると思います。 :)

8

argparsenargs パラメータをサポートします。これは、食べるパラメータの数を示します。いつ nargs="+" 1つ以上のパラメーターを受け入れるため、-b 1 2 3 4b引数にリストとして割り当てられます

# 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
46
Jakub M.

これは私のために働きました:

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

編集:

これは実際には尋ねられている質問に答えるものではないことに気づきました。 Jakubは正しい解決策を持っています。

5
bobtheterrible

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

スクリプトはこれらの入力を実際のリストに変換する必要があります。

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 必要なリストを収集します。

1
Inbar Rose

only引数がリストとセパレータである場合、比較的簡単に行うことができます:

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]"
1
Roland Smith

完全にするためにこれを追加するだけです。私はこのアプローチを見ていないことに驚きました。

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

これは基本的な例にすぎませんが、検証値を追加したり、大文字に変換するなどの方法で値を変換したりすることもできます。

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