Categories: Python

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

この記事では、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

keyvalueをまとめて受け取りたい場合は、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

辞書のkeyvalueもバラバラに受け取ることができる。

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
引数の数と指定した配列の要素数が同じじゃないと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つ付けます。すると、辞書のkeyvalueを使ってキーワード呼び出しをします。

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

アンパックすることでめんどくさいコードを簡潔に記述することができます。何気にけっこう使うので覚えておくと便利です!

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

ゆうまる

独学でプログラミングを勉強しているおじさん。いろんな言語を勉強したが浅く広くなためあまり仕事につながらない。また忘れっぽいため自分のブログを備忘録としても使っている。産まれてこのかたずっとネコを飼ってる生粋のネコ派。最近お腹が出てきて筋トレに奮闘中!

View Comments

Recent Posts

【Dart】コンストラクタのデフォルト引数について

Dartのコンストラクタのデフォルト引数…

2週間 ago

【Unity】有料アセットを無料で手に入れる方法

この記事では、Unityの有料アセットを…

4か月 ago

【Python】任意の秒数だけ処理を一時停止する方法【sleep()関数】

この記事では、Pythonで任意の秒数だ…

1年 ago

【Python】Wordの文書の新規作成と読み書き

この記事では、Pythonを使ってWor…

1年 ago

【Python】メタクラスって結局なんなの?

この記事では、Pythonのメタクラスに…

1年 ago