概要
小ネタ。Python 3.0で追加された仕様です。
知ってるとちょっと楽できます。
以下のPEPです。
名前は、Extended Iterable Unpacking って感じのちょっとむずかしそうな
名前ですが、実際にコード見てみるとすぐ意味が分かります。
list01 = list(range(5)) first, *rest = list01
上記を実行すると
first=0 rest=[1, 2, 3, 4]
となります。つまり、「*」を付けた変数に残りがアンパックされます。
以前は、こう書いてました。
list01 = list(range(5)) first, rest = list01[0], list01[1:]
アンパックする部分は、左辺の末尾にないといけないわけではなく
str01 = 'hello world'
first, *rest, last = str01
のように記述することもできます。
この場合、ちゃんと first, last にも先頭と末尾の値が入ります。
サンプル
# ----------------------------------------------- # PEP 3132 Extended Iterable Unpacking は # Python 3.0 から追加された機能。 # # 「*」を付けた変数に残りの値がアンパックされる # ----------------------------------------------- # 以下のように iterable を右辺において # 左辺に複数の変数で受ける記述は昔からあったが # そこに、「*」を付与した変数を置くと # ここでアンパックされる。また、後ろに # アンパックではない通常の変数を置いても # 適切に解釈して値を設定してくれる。 # ----------------------------------------------- str01 = 'hello world' first, *rest, last = str01 pr('first', first) pr('rest', rest) pr('last', last) # なので、シーケンスの先頭とそれ以外を分ける場合に seq01 = list(range(10)) first, rest = seq01[0], seq01[1:] pr('first', first) pr('rest', rest) # とする必要がなく、以下のように書ける first, *rest = seq01 pr('first', first) pr('rest', rest) # 同じことが for ステートメントでも適用できて以下のように書ける it01 = [tuple('hello'), tuple('world')] for _, *x, _ in it01: print(x) # 一つしか要素がない iterable の場合もちゃんと動く oneitem = [1] first, *rest = oneitem pr('first', first) pr('rest', rest) # さすがに要素がゼロの場合はエラーになる try: noitem = [] first, *rest = noitem pr('first', first) pr('rest', rest) except ValueError as e: pr('noitem', e)
実行すると以下のようになります。
first='h' rest=['e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l'] last='d' first=0 rest=[1, 2, 3, 4, 5, 6, 7, 8, 9] first=0 rest=[1, 2, 3, 4, 5, 6, 7, 8, 9] ['e', 'l', 'l'] ['o', 'r', 'l'] first=1 rest=[] noitem=ValueError('not enough values to unpack (expected at least 1, got 0)',)
ソースは、以下でも見れます。
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場