可変数の引数を関数に渡すことはできますか?


345

CまたはC ++でvarargsを使用するのと同様の方法で:

fn(a, b)
fn(a, b, c, d, ...)

5
私はポッドキャスト53に名誉ある宝くじを言及しています:itc.conversationsnetwork.org/shows/…–
デビッドサイクス

2
これはロットさんと一緒に行かなきゃ。Pythonのドキュメントでこれに関する信頼できる回答をすばやく得ることができ、さらにドキュメント内の他の内容についての感触をつかむことができます。Pythonでの作業を計画している場合は、それらのドキュメントを理解しておくと役に立ちます。
ブライアンニール

@DavidSykesリンクが壊れています
Dave Liu

回答:


446

はい。キーワード以外の引数*argsとして使用できます。その後、任意の数の引数を渡すことができます。

def manyArgs(*arg):
  print "I was called with", len(arg), "arguments:", arg

>>> manyArgs(1)
I was called with 1 arguments: (1,)
>>> manyArgs(1, 2, 3)
I was called with 3 arguments: (1, 2, 3)

ご覧のとおり、Pythonはすべての引数を持つ単一のタプルとして引数をアンパックします。

キーワード引数については、Skurmedelの回答に示されているように、それらを個別の実際の引数として受け入れる必要があります


8
また、重要な...関数に未知の数の引数を渡さなければならないときがあるかもしれません。このような場合は、「args」というリストを作成して「manyArgs」を呼び出し、それを「manyArgs(* args)」のようにmanyArgsに渡します
wilbbe01

4
これは近いですが、残念ながら一般的ではありません。でmanyArgs(x = 3)失敗しTypeErrorます。スクメデルの答えはこれに対する解決策を示しています。重要な点は、関数の一般的なシグネチャはf(*list_args, **keyword_args)(ではないf(*list_args))であることです。
Eric O Lebigot 2013年

2
タイプはargsですtupleキーワードargsをkwargs意味します。タイプはです。kwargsdictionary
RoboAlex

1
for arg in args:渡された引数を反復するためだけ
MasterControlProgram

228

巻き戻し投稿に追加:

複数のKey-Value引数を送信することもできます。

def myfunc(**kwargs):
    # kwargs is a dictionary.
    for k,v in kwargs.iteritems():
         print "%s = %s" % (k, v)

myfunc(abc=123, efh=456)
# abc = 123
# efh = 456

そして、あなたは2つを混合することができます:

def myfunc2(*args, **kwargs):
   for a in args:
       print a
   for k,v in kwargs.iteritems():
       print "%s = %s" % (k, v)

myfunc2(1, 2, 3, banan=123)
# 1
# 2
# 3
# banan = 123

これらは宣言と呼び出しの両方の順序である必要があります。つまり、関数のシグネチャは* args、** kwargsであり、その順序で呼び出す必要があります。


2
myfunc(abc = 123、def = 456)がどのように機能するかはわかりませんが、私の場合(2.7)では、SyntaxErrorを取得せずにこの関数に「def」を渡すことはできません。これはdefがpythonで意味を持つためだと思います。代わりにmyfunc(abc = 123、fgh = 567)を試してください。(それ以外の場合は、素晴らしい答えとそれに対する感謝!)
Dannid 2013

@Dannid:わからない... 2.6でも3.2でも動作しません。名前を変更します。
Skurmedel 2013

「その順序で呼び出された」と言うとき、その順序で渡されたという意味ですか?または、他の何か?
Nikhil Prabhu 2016

1
@NikhilPrabhu:うん。キーワード引数は、呼び出すときに最後に来る必要があります。呼び出しでもキーワード以外の引数がある場合は、常に最後になります。
Skurmedel 2016

1
Pythonの3の場合:ちょうど交換print aしてprint(a)、そしてkwargs.iteritems():持ちますkwargs.items()
MasterControlProgram

22

もしそうなら、Skurmedelのコードはpython 2用です。これをpython 3に適合させるには、に変更iteritemsitemsてかっこをに追加しますprint。これは、私のような初心者がぶつかるのを防ぐことができます: AttributeError: 'dict' object has no attribute 'iteritems'そして、これが起こっている理由を他の場所で検索します(たとえば、NetworkXのwrite_shp()を使用しようとすると、エラー「「dict」オブジェクトには属性「iteritems」がありません)。

def myfunc(**kwargs):
for k,v in kwargs.items():
   print("%s = %s" % (k, v))

myfunc(abc=123, efh=456)
# abc = 123
# efh = 456

そして:

def myfunc2(*args, **kwargs):
   for a in args:
       print(a)
   for k,v in kwargs.items():
       print("%s = %s" % (k, v))

myfunc2(1, 2, 3, banan=123)
# 1
# 2
# 3
# banan = 123

12

他の優れた投稿に追加します。

引数の数を指定たくない場合、それらのキーを使用たい場合があります(辞書で渡された1つの引数がメソッドで使用されていない場合、コンパイラーは文句を言います)。

def manyArgs1(args):
  print args.a, args.b #note args.c is not used here

def manyArgs2(args):
  print args.c #note args.b and .c are not used here

class Args: pass

args = Args()
args.a = 1
args.b = 2
args.c = 3

manyArgs1(args) #outputs 1 2
manyArgs2(args) #outputs 3

その後、次のようなことができます

myfuns = [manyArgs1, manyArgs2]
for fun in myfuns:
  fun(args)

2
def f(dic):
    if 'a' in dic:
        print dic['a'],
        pass
    else: print 'None',

    if 'b' in dic:
        print dic['b'],
        pass
    else: print 'None',

    if 'c' in dic:
        print dic['c'],
        pass
    else: print 'None',
    print
    pass
f({})
f({'a':20,
   'c':30})
f({'a':20,
   'c':30,
   'b':'red'})
____________

上記のコードが出力されます

None None None
20 None 30
20 red 30

これは、ディクショナリを使用して変数引数を渡すのと同じです。


3
これはひどいコードです。はるかに良いでしょう:f = lambda **dic: ' '.join(dic.get(key, 'None') for key in 'abc')
metaperture 2016

0

すでに述べたすばらしい答えに加えて、それを行う別の方法は、オプションの名前付き引数を位置で渡すことができるという事実に依存します。例えば、

def f(x,y=None):
    print(x)
    if y is not None:
        print(y)

収量

In [11]: f(1,2)
1
2

In [12]: f(1)
1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.