web-dev-qa-db-ja.com

PythonにTupleの理解がないのはなぜですか?

私たちみんなが知っているように、次のようなリスト内包表記があります。

[i for i in [1, 2, 3, 4]]

そして、次のような辞書の理解があります

{i:j for i, j in {1: 'a', 2: 'b'}.items()}

しかし

(i for i in (1, 2, 3))

Tuple内包表記ではなく、ジェネレータになります。何故ですか?

Tupleは不変であると私は思いますが、これは答えではないようです。

256
Shady Xu

ジェネレータ式を使うことができます。

Tuple(i for i in (1, 2, 3))

しかし...括弧はすでに…ジェネレータ式に使用されています。

366
Martijn Pieters

Raymond Hettinger(Pythonのコア開発者の一人)はこれをタプルについて言うために持っていました 最近のツイート

#pythonのヒント:一般的に、リストは繰り返し用です。構造体のタプルリストは同種です。異種のタプル。可変長のリスト。

これは(私にとっては)、シーケンス内の項目が生成元によって生成されるのに十分に関連している場合、それはリストになるはずであるという考えをサポートしています。 Tupleは反復可能で、単なる不変のリストのように見えますが、実際にはPythonのCの構造体と同等です。

struct {
    int a;
    char b;
    float c;
} foo;

struct foo x = { 3, 'g', 5.9 };

pythonになる

x = (3, 'g', 5.9)
60
chepner

Python 3.5以降 、splat *アンパック構文を使ってジェネレータ式を解凍することもできます。

*(x for x in range(10)),
43
czheo

理解は項目をループまたは反復してコンテナに割り当てることで機能します。タプルは割り当てを受け取ることができません。

タプルが作成されると、それを追加、拡張、または割り当てすることはできません。 Tupleを変更する唯一の方法は、そのオブジェクトの1つをそれ自身に割り当てることができる場合です(Tuple以外のコンテナです)。なぜなら、タプルはその種のオブジェクトへの参照を保持しているだけだからです。

また、Tupleには独自のコンストラクタTuple()があり、これをイテレータに渡すことができます。つまり、タプルを作成するには、次のようにします。

Tuple(i for i in (1,2,3))
20
Inbar Rose

別のポスターmacmが述べたように、ジェネレータからTupleを作成する最も早い方法はTuple([generator])です。


性能比較

  • リスト内包:

    $ python3 -m timeit "a = [i for i in range(1000)]"
    10000 loops, best of 3: 27.4 usec per loop
    
  • リスト内包表記からのタプル:

    $ python3 -m timeit "a = Tuple([i for i in range(1000)])"
    10000 loops, best of 3: 30.2 usec per loop
    
  • ジェネレータからのタプル:

    $ python3 -m timeit "a = Tuple(i for i in range(1000))"
    10000 loops, best of 3: 50.4 usec per loop
    
  • 開梱からのタプル:

    $ python3 -m timeit "a = *(i for i in range(1000)),"
    10000 loops, best of 3: 52.7 usec per loop
    

私のバージョンのpython

$ python3 --version
Python 3.6.3

ですから、パフォーマンスが問題にならないのでなければ、常にリスト内包表記からTupleを作成するべきです。

17
Tom

私の一番の推測は、彼らが括弧を使い果たし、「醜い」構文を追加することを保証するのに十分に役立つとは思わないことです。

13
mgilson

タプルをリストのように効率的に追加することはできません。

そのため、Tupleの内包表記では、内部的にリストを使用してからTupleに変換する必要があります。

それはあなたが今していることと同じでしょう:Tuple([理解])

6
macm

括弧はタプルを作成しません。別名one =(two)はタプルではありません。唯一の回避策は、one =(two、)またはone = Tuple(two)のどちらかです。だから解決策は:

Tuple(i for i in myothertupleorlistordict) 
1
ilias iliadis