Pythonの可変長引数(*args, **kwargs)にリスト、タプル、辞書を展開して渡す

463, 2022-05-02

目次

Pythonの関数の可変長引数

Pythonでは関数に可変長引数を定義できます。
これは具体的な引数の名前を省略し、適当に引数を扱う方法です。

この記事では可変長引数に対してリストやタプル、辞書などを展開して渡す方法について解説します。

関連記事


可変長引数、*args

たとえば↓のように関数を定義します。

def func(*args):
    print(args)


func(1, 2, 3)


↑のコードを実行すると↓のような結果になります。

(1, 2, 3)

関数側(func)の*argsという引数が可変長引数です。
この引数を使うと、関数の具体的な引数名を省略することができます。
*argsにはタプルで関数の呼び出し側の引数がパックされます。

そのため*argsに対して添え字でアクセスすると呼び出し側の引数を取り出せます。

print(args[0])  # 1
print(args[1])  # 2
print(args[2])  # 3

可変長キーワード引数

可変長引数にはキーワード引数版もあります。
たとえば↓のように関数を定義します。

def func(**kwargs):
    print(kwargs)


func(a=1, b=2)

↑のコードを実行すると↓のような結果になります。

{'a': 1, 'b': 2}

関数側の**kwargsという引数は可変長のキーワード引数です。
これは辞書として機能します。

関数の呼び出し側でfunc(a=1, b=2)などと引数を指定しすると、キーと値が**kwargsにパックされて渡されます。
**kwargsは辞書なので、辞書として引数にアクセスできます。

print(kwargs['a'])  # 1
print(kwargs.get('b'))  # 2

可変長引数にリストをアンパックして渡す

リストやタプルは*lisのようにアスタリスクを付けるとアンパック(展開)することができます。
つまりリストなどの各要素が展開されて関数の引数に渡されるということになります。

def func(*args):
    print(args)


lis = [1, 2, 3]
func(*lis)
(1, 2, 3)

これは可変長引数でない場合も渡すことができます。
ただしその場合は引数の数と、アンパックした要素の数が一致している必要があります。

def func(a, b, c):
    print(a, b, c)


lis = [1, 2, 3]
func(*lis)
1 2 3

リストでなくタプルについても同様にしてアンパック可能です。

可変長キーワード引数に辞書をアンパックして渡す

辞書は**dのようにアスタリスクを2つつけると、アンパックできます。
可変長キーワード引数を持つ関数などに辞書を展開して渡せます。

def func(**kwargs):
    print(kwargs)


d = {'a': 1, 'b': 2}
func(**d)
{'a': 1, 'b': 2}

これは可変長キーワード引数でない場合も同様です。
この場合も引数の数と辞書の要素の数が一致している(キーが存在している)必要があります。

def func(a, b):
    print(a, b)


d = {'a': 1, 'b': 2}
func(**d)
1 2

可変長引数のミックス

*args**kwargsは同じ関数に存在することができます。

def func(*args, **kwargs):
    pass

この場合の引数のアンパックについても見てみたいと思います。
リストやタプルをアンパックした場合は、*argsに引数が入ります。

def func(*args, **kwargs):
    print(args)
    print(kwargs)


lis = [1, 2, 3]
func(*lis)
(1, 2, 3)
{}

辞書をアンパックした場合は**kwargsに引数が入ります。

def func(*args, **kwargs):
    print(args)
    print(kwargs)


d = {'a': 1, 'b': 2}
func(**d)
()
{'a': 1, 'b': 2}

リストやタプル、そして辞書を同時にアンパックした場合はそれぞれ適当な引数に入ります。

def func(*args, **kwargs):
    print(args)
    print(kwargs)


lis = [1, 2, 3]
d = {'a': 1, 'b': 2}
func(*lis, **d)
(1, 2, 3)
{'a': 1, 'b': 2}

珍しい技、zipをご覧あれ

組み込み関数のzip()dict()を組み合わせて使うと2つのリストから辞書を作れます。
これを利用するとリストを辞書として展開できます。
たとえば↓のようにです。

def func(**kwargs):
    print(kwargs)


keys = ['a', 'b']
vals = [1, 2]
func(**dict(zip(keys, vals)))
{'a': 1, 'b': 2}

ちなみにzip()の結果をlist()に渡した場合は要素がタプルになっているリストになります。
これを展開した場合は*argsに結果が入ります。

def func(*args):
    print(args)


keys = ['a', 'b']
vals = [1, 2]
func(*list(zip(keys, vals)))
(('a', 1), ('b', 2))
(^ _ ^)

zipおもしろいね

(・ v ・)

器用な関数だな

おわりに

今回はPythonの可変長引数(*args, **kwargs)にリストやタプル、辞書を展開して渡す方法について解説しました。
可変長引数は便利なので覚えておいて損はない感じですね。

(^ _ ^)

めんどくさい場合は可変長引数を使おう

(・ v ・)

アンパックして引数を渡せるよ





この記事のアンケートを送信する