Pythonでリスト、タプル、辞書を展開して引数にする

Pythonのリスト・タプル・辞書を展開して関数に引数として渡す方法について解説します。

Pythonでリスト、タプル、辞書を展開して引数にする

Pythonでは、関数の呼び出しの際にリストやタプル、辞書を展開(アンパック)して引数として渡すことができます。

リストやタプルには*(アスタリスク1つ)、辞書には**(アスタリスク2つ)を頭につけて引数にします。

Pythonの関数の定義時に、任意の数の引数を受け取れるようにする可変長引数の使い方については、以下の記事を参考にしてください。

リスト・タプルの展開(アンパック)

リスト(配列)やタプルの頭に*をつけて引数として渡すと、それぞれの要素が展開されて個別の引数として関数内で使用することができます。

# リスト・タプルを展開する

def my_sum(num1, num2):
    print(f"num1: {num1}")
    print(f"num2: {num2}")
    return num1 + num2

nums = [5, 10]

# リストを展開して引数にする
ans = my_sum(*nums)
# num1: 5
# num2: 10

print(ans)
# 15


# リストを直接入力しても展開される
ans = my_sum(*[15, 20])
# num1: 15
# num2: 20

print(ans)
# 35

# タプルでも同様の使い方
nums_tuple = (5, 10)
ans = my_sum(*nums_tuple)
# num1: 5
# num2: 10

print(ans)
# 15

引数の数と要素数が一致していないとTypeErrorになります。

# 引数の数と要素数が一致していない場合

nums = [5, 10, 20]

# リストを展開して引数にする
ans = my_sum(*nums)
# TypeError: my_sum() takes 2 positional arguments but 3 were given

可変長引数が設定されている場合

任意の長さの引数を取ることができる可変長引数が設定されている関数の場合には、より柔軟に引数を渡すことができるようになります。

# 可変長引数が設定されている場合

# 可変長引数を持つ関数
def my_sum(*args):
    print(f"args: {args}")
    return sum(args)

nums = [5, 10]
nums2 = [5, 10, 15, 20]

# リストを展開して引数にする
ans = my_sum(*nums)
# args: (5, 10)

print(ans)
# 15

ans2 = my_sum(*nums2)
# args: (5, 10, 15, 20)
print(ans)
# 50

位置引数と可変長引数が設定されている場合、そこに展開(アンパック)した要素を渡すと、位置引数に相当する部分より後ろの引数が可変長引数として関数に渡されます。

# 位置引数と可変長引数が設定されている場合

# 位置引数と可変長引数を持つ関数
def my_sum(num1, num2, *args):
    print(f"num1: {num1}")
    print(f"num2: {num2}")
    print(f"args: {args}")
    return num1 + num2 + sum(args)

nums = [5, 10]
nums2 = [5, 10, 15, 20]

ans = my_sum(*nums)
# num1: 5
# num2: 10
# args: ()

print(ans)
# 15

ans2 = my_sum(*nums2)
# num1: 5
# num2: 10
# args: (15, 20)

print(ans)
# 50

デフォルト引数が設定されている場合

デフォルト引数が設定されている場合、展開(アンパック)した要素数が少なければデフォルトの引数を使用します。要素数が多ければ同じくTypeErrorになります。

# デフォルト引数が設定されている場合

def my_sum(num1=100, num2=200):
    print(f"num1: {num1}")
    print(f"num2: {num2}")
    return num1 + num2

nums = [5]

# 要素数が少ないため、デフォルト引数が使われる
ans = my_sum(*nums)
# num1: 5
# num2: 200

print(ans)
# 205

辞書の展開(アンパック)

辞書の頭に**をつけて引数として渡すと、それぞれの要素のキーを引数名、値を引数の値として展開して個別の引数として関数内で使用することができます。

引数として渡した辞書の中に、関数の定義にある引数名と同じキーがなければ、TypeErrorになります。

# 辞書を展開する

def my_sum(num1, num2):
    print(f"num1: {num1}")
    print(f"num2: {num2}")
    return num1 + num2

nums = {'num1': 5, 'num2': 10}

# 辞書を展開して引数にする
ans = my_sum(**nums)
# num1: 5
# num2: 10

print(ans)
# 15


# 辞書を直接入力しても展開される
ans = my_sum(**{'num1': 15, 'num2': 20})
# num1: 15
# num2: 20

print(ans)
# 35

# 関数で定義した引数名と同じキーがなければエラー
nums = {'num_1': 5, 'num_2': 10}
ans = my_sum(**nums)
# TypeError: my_sum() got an unexpected keyword argument 'num_1'

可変長引数が設定されている場合

可変長引数が設定されている関数の場合には、そのまま辞書として関数内で扱われます。

位置引数と同じキーがある場合には、それ以外のキーと値のみが関数内で辞書として扱われます。

# 可変長引数が設定されている場合

# 可変長引数を持つ関数
def my_function(**kwargs):
    print(f"kwargs: {kwargs}")

nums = {'num1': 10, 'num2': 20, 'num3': 30}

my_function(**nums)
# kwargs: {'num1': 10, 'num2': 20, 'num3': 30}


# 位置引数と可変長引数を持つ関数
def my_function(num1, **kwargs):
    print(f"num1: {num1}")
    print(f"kwargs: {kwargs}")

my_function(**nums)
# num1: 10
# kwargs: {'num2': 20, 'num3': 30}

デフォルト引数が設定されている場合

デフォルト引数が設定されている場合、引数名と同じ辞書のキーがあればその値が更新され、それ以外はデフォルトの値が設定されます。

渡す辞書の中に、関数の引数名と一致しないキーがある場合にはTypeErrorになります。

# デフォルト引数が設定されている場合

# 位置引数と可変長引数を持つ関数
def my_function(num1=10, num2=20, num3=30):
    print(f"num1: {num1}")
    print(f"num2: {num2}")
    print(f"num3: {num3}")

nums = {'num1': 1, 'num3': 3}

my_function(**nums)
# num1: 1
# num2: 20
# num3: 3

# 引数名と一致しないキーを持っているとエラー
nums = {'num1': 1, 'num_2': 2, 'num3': 3}
my_function(**nums)
# TypeError: my_function() got an unexpected keyword argument 'num_2'