アンパック演算子 ( ) に関するPython 3 チュートリアル*
では、一般的に「リストまたはタプル」について説明していますが、不適切な使用に関するエラー メッセージには、「シーケンス」が必要であることが示されています。
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> def f(a, b):
... return a / b
...
>>> f(*1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after * must be a sequence, not int
Python 3 の組み込み型のドキュメントには、次のシーケンス型がリストされています。
- シーケンス タイプ —
list
、tuple
、range
- テキスト シーケンス タイプ —
str
- バイナリ シーケンス タイプ —
bytes
、bytearray
、memoryview
クイックテスト:
>>> all(isinstance(x, collections.Sequence) for x in [[], (), range(1), '', b''])
True
セット タイプ (set
や などfrozenset
) とマッピング タイプ ( dict
) はここには含まれていないことに注意してください。
>>> any(isinstance(x, collections.Sequence) for x in [set(), {}])
False
私の質問:すべてのイテラブル型 (set
またはを含むdict
) がアンパック可能なのはなぜですか? TypeError
上記が示唆するように、これらはシーケンス型ではなく、順序付けられていない動作により、位置引数のアンパック時に未定義の結果が発生します。
>>> def f(a, b):
... return a / b
...
>>> f(*{4, 2})
0.5
>>> f(*{8, 2})
4.0
>>> f(*{4:1, 2:1})
0.5
>>> f(*{2:1, 8:1})
4.0