この記事では、Pythonのアンパック(unpack)について解説します。
アンパックとは、配列の要素を展開してそれぞれ変数に代入することを言います。また、関数の引数としてリストや辞書を展開して渡すこともできます。
それでは、アンパックの使い方を見ていきましょう!
アンパックの基本
アンパックは、右辺にイテラブル、左辺にイテラブルの要素の数だけ変数を用意します。そうすることで対応した変数にイテラブルの要素がそれぞれ代入されます。
変数1, 変数2 = [要素1, 要素2]
例としてタプルをアンパックしてみます:
person = (1, 'Mike', 21) # 要素数が3なので変数を3つ用意 no, name, age = person print(f'No. {no}, name: {name}, age: {age}')
実行結果
No. 1, name: Mike, age: 21
関数の戻り値をタプルでまとめた時なんかによく使用されます。
def func(): return 1, 2, 3 one, two, three = func() print(one, two, three)
実行結果
1, 2, 3
辞書のアンパック
辞書をアンパックする場合は少し特殊で、先ほどと同じ要領でアンパックすると変数にkeyのみが渡されます。
d = {'one': 1, 'two': 2, 'three': 3} v1, v2, v3 = d print(v1) # one print(v2) # two print(v3) # three
valueをアンパックしたい場合は、dict.values()メソッドを使います。
d = {'one': 1, 'two': 2, 'three': 3} v1, v2, v3 = d.values() print(v1) # 1 print(v2) # 2 print(v3) # 3
keyとvalueをまとめて受け取りたい場合は、dict.items()メソッドを使います。
d = {'one': 1, 'two': 2, 'three': 3} v1, v2, v3 = d.items() print(v1) # ('one', 1) print(v2) # ('two', 2) print(v3) # ('three', 3)
ネストされている配列のアンパック
ネストされている配列もアンパックすることができます。
t = (1, (2, 3)) a, b = t print(a) # 1 print(b) # (2, 3)
ネストされた部分も展開したい場合は、()や[]で囲うことで実現できます。
t = (1, (2, 3)) a, (b, c) = t print(a) # 1 print(b) # 2 print(c) # 3
辞書のkeyとvalueもバラバラに受け取ることができる。
d = {'one': 1, 'two': 2, 'three': 3} (k1, v1), (k2, v2), (k3, v3) = d.items() print(k1, v1) # 'one', 1 print(k2, v2) # 'two', 2 print(k3, v3) # 'three', 3
実行結果
one 1 two 2 three 3
不必要な値の受け取り
特に必要ないの値がある場合は、その値をアンダースコア(_)で受けとることで間違って使用しないようにします。
point = (1, 2, 3) x, y, _ = point print(x) # 1 print(y) # 2 print(_) # 3
アンダースコアは複数指定できます。
point = (1, 2, 3) x, _, _ = point print(x) # 1 print(_) # 3
複数の要素を受け取る
変数の前にアスタリスク(*)を付けることで複数の要素を受け取ることができます。
以下コードでは、配列の要素数に対して変数の数が少ないですが、アスタリスクの付いた変数があるため要素を複数受け取ってくれる。
t = (1, 2, 3) a, *b = t print(a) # 1 print(b) # [2, 3]
前の変数にも付けることができる。この場合、後ろの変数の数に合わせて要素を受け取ります。
t = (1, 2, 3) *a, b = t print(a) # [1, 2] print(b) # 3
ネストされている配列をアスタリスクの付いた変数で受け取ると以下のようになります。
t = (1, (2, 3)) a, *b= t print(a) # 1 print(b) # [(2, 3)]
注意としてアスタリスクを付けた変数で値を受け取ると必ずリストになる。
t = (1, 2, 3) *a, b, c = t print(a) # [1]
また、複数付けることはできません。
# これはエラー *a, *b = t
引数に配列の要素を展開して渡す
リストやタプル、辞書をアンパックして関数などの引数に渡すことができます。
リストやタプルの場合
リストやタプルを展開しながら引数に渡すには、名前の先頭に*(アスタリスク)を付けます。
def func(a, b): print(a, b) vals = [1, 2] # *配列名 func(*vals) # 1, 2
特に可変長引数の場合は、とても楽に値を引き渡せます。
def func(*args): for arg in args: print(arg) vals = [1, 2, 3] # 通常 func(vals[0], vals[1], vals[2]) # 1 # 2 # 3 # アンパック func(*vals) # 1 # 2 # 3
辞書の場合
辞書の場合は、*(アスタリスク)を2つ付けます。すると、辞書のkeyとvalueを使ってキーワード呼び出しをします。
def func(a, b): print(a, b) d = {'a': 1, 'b': 2} # **辞書 func(**d) # 1 2 # func(a=1, b=2)と同等
キーワード呼び出しなので要素の順番が異なっても問題ありません。
def func(a, b): print(a, b) d = {'b': 2, 'a': 1} # **辞書 func(**d) # 1 2 # func(b=2, a=1)と同等
辞書の可変長引数に使うと便利です。
def func(**kwargs): print(kwargs) d = {'one': 1, 'two': 2, 'three': 3} func(**d) # {'one': 1, 'two': 2, 'three': 3}
しかし、keyと引数名が一致しない場合はエラーとなります。
def func(a, b): print(a, b) d = {'a': 1, 'c': 2} func(**d) # TypeError: func() got an unexpected keyword argument 'c'
実はアスタリスク1つでも辞書を展開し、引数に渡すことができます。その場合、keyのみが渡されます。
def func(*args): for arg in args: print(arg) d = {'one': 1, 'two': 2, 'three': 3} func(*d) # one # two # three
valueのみを渡したい場合は、values()メソッドを使います。
func(*d.values()) # 1 # 2 # 3
まとめ
この記事では、Pythonのアンパックの使い方について解説しました。
アンパックすることでめんどくさいコードを簡潔に記述することができます。何気にけっこう使うので覚えておくと便利です!
それでは今回の内容はここまでです!ではまたどこかで〜( ・∀・)ノ


