2

iPython をいじってみると、驚いたことに、fそれぞれが何らかのメソッドをサポートしているオブジェクトのリストx()(つまり、 を出力する"Hi!") が次の式であることがわかりました。

(y.x() for y in f)

意味的に同等ではない

[y.x() for y in f]

最初のもの (出力としてタプルを使用) は、反復しない限り評価されないジェネレーター式になりますが、リストを使用するものは、実際には生成がすぐに行われます。

In [30]: (y.x() for y in f)
Out[30]: <generator object <genexpr> at 0x2d78d70>

しかし

In [31]: [y.x() for y in f]
Hi!
Hi!
Hi!
Hi!

これはかなり直感に反するようです。

質問: 最初の式が、リストの作成方法でジェネレーターから取得した値のタプルを生成しないのはなぜですか?


更新:これをさらに見つめると、おそらく最初のケースで起こっていることは、Pythonが2番目のケースのようにジェネレーターを評価するのではなく、ジェネレーターを含むタプルを構築しているだけであることに気付きました。

では、リスト内包表記を生成した結果としてタプルを直接取得することはできないというのは本当ですか? (私ができることを理解していますtuple([y.x() for y in f]))。ユースケースはありません。これは純粋に私の理解のためです。

4

2 に答える 2

3

タプルを読み取り専用リストとして扱う人もいますが、それは一部のコンテキストでは機能します。しかし、それはタプルのセマンティックな意図ではありません。リストは、同種の要素 (共有型の要素) の可変長構造に使用することを目的としています。タプルは、各インデックス位置に特定のタイプの要素が含まれる固定長構造を対象としています。

enumerate(lst)はその一例です。タプルの可変長リストを返します。各タプルには正確に 2 つの要素があり、最初の要素は常に整数で、2 番目の要素は fromlstです。

その理解では、タプル ジェネレーターは少し無意味です。それがおそらく理由です。

編集:

タプルを直接生成することに関しては、あなたの例よりも少し良いことができます。これも機能します:

tuple(y.x() for y in f)

これにより、ジェネレーターがtuple()メソッドに渡され、タプルが構築されますが、中間は作成されませんlist

明確にするために、 にはtuple関与していません(y.x() for y in f)が、 にはタプルがありt = 1, 2, 3ます。タプルを作るのは括弧ではありません。それはコンマです。

于 2013-10-09T21:21:54.960 に答える
0

質問: 最初の式が、リストの作成方法でジェネレーターから取得した値のタプルを生成しないのはなぜですか?

それは、そのように設計されたものではありません。PEP-289
を参照してください。チュートリアルは、答えを探し始めるのに適した場所です。ジェネレーター式式リスト-タプルを定義するためのコンマの使用について説明します


では、リスト内包表記を生成した結果としてタプルを直接取得することはできないというのは本当ですか?

いいえ - リスト内包表記とは異なり、ジェネレーターです。反復ごとに個々の要素を生成するように設計されています。

于 2013-10-10T13:37:16.157 に答える