web-dev-qa-db-ja.com

一般化の解凍

>>> LOL = [[1, 2], ['three']]
>>> [*LOL[0], *LOL[1]]
[1, 2, 'three']

よし!さようなら - itertools.chain 。とにかくあなたをあまり好きではありませんでした。

>>> [*L for L in LOL]
  File "<ipython-input-21-e86d2c09c33f>", line 1
    [*L for L in LOL]
    ^
SyntaxError: iterable unpacking cannot be used in comprehension

ああ。どうしていいものがないの?

理解の中で展開することは明白/ Pythonicのようですが、彼らはその特別なエラーメッセージを追加するのに苦労したので、それを無効にする理由がありました。それで、その構文の問題は何ですか?

31
wim

この機能が受け入れられたPy-Devメーリングリストスレッド から引用します。

だからそれは理解を残します。 IIRC、パッチの開発中に、f(*x for x in xs)十分にあいまいであるそれを禁止することにしました-f(x for x in xs)は、引数が唯一の引数である場合にのみ「裸の」ジェネレータ式になることができるため、すでにいくらか特殊なケースであることに注意してください。同じ理由が(その形式で)リスト内包表記に適用されません-f(x for x in xs)f((x for x in xs))と意味が同じですが、[x for x in xs][(x for x in xs)](これは1つの要素のリストであり、要素はジェネレーター式です)

(エンファシスマイン)

また、この機能のPython課題追跡システムを覗いてみました。実装中にディスカッションが行われる問題を見つけました。この実現に役立つ一連のメッセージが始まります- ここ GvRによって msg234766 で提示されたあいまいさの概要が紹介されています。

Link-rotのfearに、(フォーマットされた)メッセージをここに添付します:

したがって、ここでのテスト関数は次のようになります。

def f(*a, **k): print(list(a), list(k))

次に、次のようなことを試すことができます。

f(x for x in ['ab', 'cd'])

これはジェネレーター式である引数として解釈されるため、ジェネレーターオブジェクトを出力します。

しかし、今考えてみましょう:

f(*x for x in ['ab', 'cd'])

私は個人的にこれが以下と同等であると期待していました:

f(*'ab', *'cd')

IOW:

 f('a', 'b', 'c', 'd')

PEPは、ここで何をすべきかを明確にしません。ここで問題となるのは、*x for x in ...のようなものをジェネレータ式の拡張形式として解釈するべきか、それとも*argの拡張形式として解釈するべきかということです。どういうわけか、後者の方が便利で、論理的な拡張でもあると思います。

私の推論は、PEPはf(*a, *b)のようなものをサポートし、リストxの各xsに対して*xを実行するものとしてf(*x for x in xs)を解釈することはかなり論理的であるということです。

最後に、 対応するPEPの要約セクション に記載されているように、この機能は完全に除外されているわけではありません。

このPEPには、リスト内包表記、セット内包表記、および辞書内包表記内の展開演算子は含まれていませんが、これは将来の提案で除外されていません

ですから、近いうちにそれを見ることができるかもしれません(ただし、3.6ではありません:-)。

これは簡単にPEP 448 で説明されており、アンパックの一般化が導入されています。

このPEPの初期の反復では、リスト、セット、および辞書の内包表記内の演算子を、コンテナーの反復可能オブジェクトに対するフラット化演算子として解凍できました。

>>> ranges = [range(i) for i in range(5)]
>>> [*item for item in ranges]
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]

>>> {*item for item in ranges}
{0, 1, 2, 3}

これは、読みやすさと穏やかなサポートに関する強い懸念の組み合わせで満たされました。 PEPのあまり議論の余地のない側面を不利にしないために、これは提案の残りの部分では受け入れられませんでした。

ただし、これは将来変更される可能性があります。

このPEPには、リスト、セット、および辞書の内包表記内のアンパック演算子は含まれていませんが、将来の提案で除外されていません。

11
Delgan