Python

【Python】配列の要素を展開して変数に代入する方法を解説【アンパック】

この記事では、Pythonのアンパックについて解説します。アンパックとは、配列の要素を展開し、変数に代入することを言います。また、関数の引数としてリストや辞書を展開して渡すこともでき、とても便利です。それでは、アンパックの使い方を見ていきましょう!

アンパックの基本

アンパックは、右辺にイテラブルを記述し、左辺に要素の数だけ変数を用意します。

変数1, 変数2, 変数N = [要素1, 要素2, 要素N]

サンプル

以下のコードでは、要素が3つ格納されているタプルをアンパックしています。

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

不必要な値の受け取り

特に必要ないの値がある場合は、その値をアンダースコア(_)で受けとることで間違って使用しないようにします。

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
引数の数と指定した配列の要素数が同じじゃないとTypeError

特に可変長引数の場合は、とても楽に値を引き渡せます。

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つに

実はアスタリスク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のアンパックの使い方について解説しました。

アンパックを使うことで、めんどくさいコードを簡潔に記述することができます。

何気によく使うので覚えておきましょう❗️

それでは今回の内容はここまでです!ではまたどこかで〜( ・∀・)ノ

最短3か月でエンジニア転職『DMM WEBCAMP COMMIT』