◾️はじめに
今更だが、Pythonのアンパックについて扱う
目次
【0】アンパックを意識したきっかけ 1)現象概要 2)出力結果(エラーメッセージ) 3)解決案 【1】アンパック(unpack) 1)サンプル 【2】アンパックするための演算子 1)*演算子(スター演算子) 2)**演算子 3)補足:演算子を使用しないアンパック
【0】アンパックを意識したきっかけ
1)現象概要
str.format() で可変部分を複数あるときに、コレクション渡すと エラー「IndexError: Replacement index 1 out of range for positional args tuple」 が発生する
エラーが発生したサンプル
def get_message(message_format, params = None) -> str: return message_format.format(params) print(get_message("The results are {0}.", ("Hello world"))) # OK print("The results are {0}/{1}.".format("Hello world", "Hi")) # OK print(get_message("The results are {0}/{1}.", ("Hello world", "Hi"))) # NG print(get_message("The results are {0}/{1}/{2}.", ("Hello world", "Hi", "Good moring"))) # NG
2)出力結果(エラーメッセージ)
The results are Hello world.
The results are Hello world/Hi.
Traceback (most recent call last):
File "/Users/kobayashidaisuke/work/sample.py", line 7, in <module>
print(get_message("The results are {0}/{1}.", ("Hello world", "Hi"))) # NG
File "/Users/kobayashidaisuke/work/sample.py", line 3, in get_message
return message_format.format(params)
IndexError: Replacement index 1 out of range for positional args tuple
3)解決案
* str.format() に渡す際に、*演算子(スター演算子)による アンパック(unpack)をして渡す => で、この「*演算子」について深掘りしてみた
サンプル
def get_message(message_format, params = None) -> str: return message_format.format(*params) # ★注目★ *paramsにした print(get_message("The results are {0}.", ("Hello world"))) # ここが「H」しか出なくてNGになった、、、 print(get_message("The results are {0}/{1}.", ("Hello world", "Hi"))) # OK print(get_message("The results are {0}/{1}/{2}.", ("Hello world", "Hi", "Good moring"))) # OK
補足:最終的なOKコード
def get_message(message_format, *params) -> str: return message_format.format(*params) print(get_message("The results are NONE.")) # OK print(get_message("The results are {0}.", "Hello world")) # OK print(get_message("The results are {0}/{1}.", "Hello world", "Hi")) # OK print(get_message("The results are {0}/{1}/{2}.", "Hello world", "Hi", "Good moring")) # OK
【1】アンパック(unpack)
* コレクションなどを展開する機能 => 言葉より以下のサンプルを見た方が理解が早い
1)サンプル
demo_list = ("Hello", "World", "!!?") print(demo_list) # ('Hello', 'World', '!!?') print(*demo_list) # Hello World !!?
【2】アンパックするための演算子
1)*演算子(スター演算子)
* リストやタプルをアンパックする
2)**演算子
* 辞書をアンパックする # 「ダブルスター演算子」ってよぶ?
def hello(key1, key2, key3): print(f"key1={key1}/key2={key2}/key3={key3}") demo_dict = { "key1": "val1", "key2": "val2", "key3": "val3" } print(demo_dict) # アスタリスクを2つ付けて辞書を展開 hello(**demo_dict)
3)補足:演算子を使用しないアンパック
a, b = ["Hello", "World"] print(a) # Hello print(b) # World
参考文献
https://arika-blog.com/python-unpack/
https://note.nkmk.me/python-tuple-list-unpack/#_
関連記事
Python ~ 基本編 / 文字列 ~
https://dk521123.hatenablog.com/entry/2019/10/12/075251
Python ~ 基本編 / 型指定・Typing ~
https://dk521123.hatenablog.com/entry/2021/12/23/231559
Python ~ 基本編 / 外部コマンド実行 ~
https://dk521123.hatenablog.com/entry/2021/08/04/224716
Python ~ 可変長引数 / args, kwargs ~
https://dk521123.hatenablog.com/entry/2023/11/01/000915
Python ~ ウォルラス演算子 (:=) ~
https://dk521123.hatenablog.com/entry/2024/07/18/002712
Python ~ Requestsライブラリ ~
https://dk521123.hatenablog.com/entry/2024/05/24/095909
Python ~ TOML ~
https://dk521123.hatenablog.com/entry/2024/01/27/000110