関数に引数を渡す際、渡したいデータがすでにリストやタプルとしてまとまっている場合があります。
通常であれば、リストの要素をインデックスで一つずつ取り出して引数に指定する必要がありますが、Pythonではアスタリスク(*)を使用することで、リストの中身を「展開」して関数に渡すことができます。
この記事では、リストやタプルを関数の位置引数としてまとめて渡す方法(アンパック呼び出し)について解説します。
引数展開(アンパック)とは
関数を呼び出す際、リストやタプルの前に * を付けると、その要素が分解され、関数の位置引数として順番に割り当てられます。
構文:
関数名(*リスト変数)
例えば、3つの要素を持つリストを * 付きで渡すと、関数側では3つの独立した引数として受け取られます。
具体的なコード例
例として、直方体の「幅」「高さ」「奥行き」を受け取り、体積を計算する関数を使用します。
1. インデックス指定による呼び出し(従来の方法)
データがリストにある場合、通常は以下のように記述します。
def calculate_box_volume(width, height, depth):
"""直方体の体積を計算する"""
return width * height * depth
# サイズデータ(幅, 高さ, 奥行き)
box_dimensions = [15, 10, 25]
# インデックスで一つずつ指定して渡す
volume = calculate_box_volume(box_dimensions[0], box_dimensions[1], box_dimensions[2])
print(f"体積: {volume}")
この方法は、引数の数が増えるほど記述が長くなり、可読性が低下します。
2. 引数展開を使った呼び出し(推奨)
* を使ってリストを展開して渡します。
# リストの前に * を付けて渡す
volume_unpacked = calculate_box_volume(*box_dimensions)
print(f"体積 (展開): {volume_unpacked}")
実行結果:
体積: 3750
体積 (展開): 3750
calculate_box_volume(*[15, 10, 25]) は、内部的に calculate_box_volume(15, 10, 25) と解釈され、実行されます。非常に簡潔に記述できることがわかります。
注意点:要素数の一致
この方法を使用する場合、リストの要素数と関数が求める必須引数の数が一致している必要があります。
数が合わない場合、TypeError が発生します。
# 要素が足りない場合
small_list = [10, 20]
# calculate_box_volume(*small_list)
# TypeError: missing 1 required positional argument: 'depth'
# 要素が多すぎる場合
large_list = [10, 20, 30, 40]
# calculate_box_volume(*large_list)
# TypeError: takes 3 positional arguments but 4 were given
ただし、関数側が可変長引数(*args)を受け取るように定義されている場合は、任意の数の要素を持つリストを渡すことができます。
def sum_all(*values):
return sum(values)
numbers = [1, 2, 3, 4, 5]
print(sum_all(*numbers)) # 15
まとめ
- 関数呼び出し時にリストやタプルの前に
*を付けると、要素が展開されて位置引数として渡されます。 func(*my_list)はfunc(my_list[0], my_list[1], ...)と等価です。- 引数の数とリストの要素数が一致している必要があります。
データベースやファイルから読み込んだ1行分のデータを、そのまま処理関数に流し込む際などに非常に役立つテクニックです。
