Pythonでは、リストや辞書の中身を「バラして」渡すテクニックがよく使われます。
これを「アンパック(unpack)」と呼びます。
一見難しそうに見えますが、慣れるとPythonらしいきれいなコードが書けるようになります。
この記事では、アンパックの基本から、よく使われるパターンまでをわかりやすく整理します!
アンパックとは?
アンパックとは、リストや辞書の中身をバラして、関数などに渡すテクニックです。
-
*
を使うとリストやタプルをバラして渡せます。 -
**
を使うと辞書をバラして渡せます。
これを使うことで、複数の値をスマートに処理できるようになります。
* を使ったアンパックの基本
リストやタプルのアンパック
リストの中身をバラして出力してみましょう。
lst = [1, 2, 3]
print(*lst)
出力:
1 2 3
このように、リストの各要素がスペース区切りで出力されました。
*
を付けることで、リストそのものではなく「中身だけ」を取り出して渡すことができます。
関数へのリストアンパック
たとえば、関数に複数の引数を渡したい場合にも便利です。
def add(a, b, c):
return a + b + c
lst = [1, 2, 3]
print(add(*lst))
出力:
6
普通なら add(1, 2, 3)
と個別に渡す必要がありますが、
リストの中に値がまとまっているときでも *lst
と書くだけでOKです!
** を使ったアンパックの基本
辞書のアンパック
今度は辞書をバラして関数に渡してみます。
def greet(name, age):
print(f"{name} is {age} years old.")
info = {'name': 'Alice', 'age': 25}
greet(**info)
出力:
Alice is 25 years old.
**info
とすることで、
name='Alice'
-
age=25
という形で、それぞれのキーと値を対応させて関数に渡すことができました!
【補足】辞書のアンパックは「キーワード引数」に変換する
辞書を **辞書
の形でアンパックするときは、
その中身(キーと値)をキーワード引数にバラして渡すためだけに使います。
そのため、
- キーワード引数を受け取れる関数(例:
def greet(name, age):
)には渡せる - 受け取れないキーワードを持つ辞書を渡すとエラーになる
注意しましょう!
(参考例:失敗するケース)
info = {'name': 'Alice', 'age': 25}
print(**info) # → エラー:print() got an unexpected keyword argument 'name'
print()
はキーワード引数を受け付けないためエラーになります。
【さらに補足】print()は一部キーワード引数を受け付けます
実は print()
関数には
- sep:複数オブジェクトの間に挟む文字(デフォルトは半角スペース)
- end:出力の最後に付ける文字(デフォルトは改行
\n
) - file:出力先(デフォルトは標準出力。ファイルオブジェクトを指定可能)
- flush:出力を強制的にフラッシュするか(デフォルトはFalse)
など、もともと受け付けるキーワード引数が存在します。
そのため、例えば次のような辞書は渡してもエラーになりません。
(例:成功するケース)
info = {'sep': '!', 'end': '!!\n'}
print('いくぞ', 1, 2, 3, 'ダー', **info)
出力:
いくぞ!1!2!3!ダー!!
このように、辞書のキーが関数で受け取れる名前なら、アンパックして渡すことができます。
一方、受け取れない名前(name
など)ならエラーになります。
実践編:アンパックの応用
リストの結合にも使える
リスト同士をスマートに合体させることもできます。
a = [1, 2]
b = [3, 4]
c = [*a, *b]
print(c)
出力:
[1, 2, 3, 4]
普通はループで追加したりしますが、アンパックを使えば簡単にリスト同士を結合できます!
関数の可変長引数(*args, **kwargs)
ここまで学んだアンパックは、関数定義にも応用できます!
def func(*args, **kwargs):
print(args)
print(kwargs)
func(1, 2, 3, name="Alice", age=25)
出力:
(1, 2, 3)
{'name': 'Alice', 'age': 25}
-
*args
で複数の引数をまとめて受け取る -
**kwargs
でキーワード引数(名前付きの引数)をまとめて受け取る
こうした「自由な数の引数」を受けるテクニックにもアンパックは使われています!
ここで注意したいのは、
- 関数定義側(
*args
,**kwargs
)では、引数をまとめる(パックする) - 関数呼び出し側(
*リスト
,**辞書
)では、引数をバラす(アンパックする)
という違いがあることです。
なお、パックが行われる条件は、
関数定義時に仮引数リストの中で *
や **
を使った場合です。
args
や kwargs
という名前自体には特別な意味はなく、名前は自由につけることができます(慣例として args
, kwargs
がよく使われています)。
アンパックの注意点
-
*リスト
や**辞書
を使うときは、対応する数や名前が正しいかに注意しましょう。 - 間違った数や違う名前の引数を渡すと、エラーになります。
(例)
def add(a, b):
return a + b
lst = [1, 2, 3]
print(add(*lst)) # → エラー!
リストの要素数(ここでは3個)が関数の引数(2個)と合っていないのでエラーになります。
発展編:拡張アンパック(Extended Iterable Unpacking)
Pythonでは、関数の引数だけでなく、
変数への代入時にも *
を使って複数の値をまとめることができます。
これを「拡張アンパック」と呼びます。
(例)
say = 1, 2, 3, 'ダー'
*count, last = say
print(count) # [1, 2, 3]
print(last) # 'ダー'
このように、リストやタプルの一部をまとめて受け取ることができます。
仮引数と拡張アンパックの違い
パターン | データ型 |
---|---|
関数の仮引数 *args
|
タプルになる |
拡張アンパック *count
|
リストになる |
使う場面によってデータ型も異なるので注意しましょう!
まとめ
-
*
→ リストやタプルをバラして渡す -
**
→ 辞書をバラして渡す - 関数にまとめて引数を渡したり、リストを簡単に結合したりするときに大活躍!
アンパックを使いこなすと、Pythonらしいスッキリしたコードが書けるようになると思いました。
使いこなせるようにしていきます!