私たちみんなが知っているように、次のようなリスト内包表記があります。
[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
は不変であると私は思いますが、これは答えではないようです。
ジェネレータ式を使うことができます。
Tuple(i for i in (1, 2, 3))
しかし...括弧はすでに…ジェネレータ式に使用されています。
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)
Python 3.5以降 、splat *
アンパック構文を使ってジェネレータ式を解凍することもできます。
*(x for x in range(10)),
理解は項目をループまたは反復してコンテナに割り当てることで機能します。タプルは割り当てを受け取ることができません。
タプルが作成されると、それを追加、拡張、または割り当てすることはできません。 Tupleを変更する唯一の方法は、そのオブジェクトの1つをそれ自身に割り当てることができる場合です(Tuple以外のコンテナです)。なぜなら、タプルはその種のオブジェクトへの参照を保持しているだけだからです。
また、Tupleには独自のコンストラクタTuple()
があり、これをイテレータに渡すことができます。つまり、タプルを作成するには、次のようにします。
Tuple(i for i in (1,2,3))
別のポスター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を作成するべきです。
私の一番の推測は、彼らが括弧を使い果たし、「醜い」構文を追加することを保証するのに十分に役立つとは思わないことです。
タプルをリストのように効率的に追加することはできません。
そのため、Tupleの内包表記では、内部的にリストを使用してからTupleに変換する必要があります。
それはあなたが今していることと同じでしょう:Tuple([理解])
括弧はタプルを作成しません。別名one =(two)はタプルではありません。唯一の回避策は、one =(two、)またはone = Tuple(two)のどちらかです。だから解決策は:
Tuple(i for i in myothertupleorlistordict)