4

アンパック演算子 ( ) に関する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 の組み込み型のドキュメントには、次のシーケンス型がリストされています。

  • シーケンス タイプ — listtuplerange
  • テキスト シーケンス タイプ —str
  • バイナリ シーケンス タイプ — bytesbytearraymemoryview

クイックテスト:

>>> 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
4

2 に答える 2

4

これは、(少なくとも) Python 3.5.2 では当てはまりません。おそらく問題として認識され、使用しているバージョンより後のバージョンで変更されました。メッセージは、シーケンスではなくiterableをより適切に読み取るようになりました

https://bugs.python.org/issue4806を参照してください

>>> def foo(*args):
...     print(*args)
...
>>> foo(*1)
TypeError: foo() argument after * must be an iterable, not int
于 2016-10-28T16:17:33.413 に答える