web-dev-qa-db-ja.com

リスト内包表記から2つのリストを返すことは可能ですか?

リスト内包から2つのリストを返すことは可能ですか?まあ、これは明らかに機能しませんが、次のようなものです:

rr, tt = [i*10, i*12 for i in xrange(4)]

したがって、rrttはどちらも、それぞれi*10i*12の結果を含むリストです。どうもありがとう

42
LarsVegas
>>> rr,tt = Zip(*[(i*10, i*12) for i in xrange(4)])
>>> rr
(0, 10, 20, 30)
>>> tt
(0, 12, 24, 36)
67
jamylak

2つの内包表記リストを作成することをお勧めします(少なくとも長いリストの場合)。 ベスト投票の回答は遅いは、従来のforループよりもさらに遅くなる可能性があることに注意してください。 リストの理解がより速く、より明確になりました

python -m timeit -n 100 -s 'rr=[];tt = [];' 'for i in range(500000): rr.append(i*10);tt.append(i*12)' 
10 loops, best of 3: 123 msec per loop

> python -m timeit -n 100 'rr,tt = Zip(*[(i*10, i*12) for i in range(500000)])' 
10 loops, best of 3: 170 msec per loop

> python -m timeit -n 100 'rr = [i*10 for i in range(500000)]; tt = [i*10 for i in range(500000)]' 
10 loops, best of 3: 68.5 msec per loop

一度に複数のリストの作成をサポートするリストの内包を見るといいでしょう。

しかしながら、

従来のループを使用する利点を活用できる場合(正確には、中間の計算)、そして、それは可能であるループ(またはiteratorを使用したgenerator/yield)の方が良いでしょう。次に例を示します。

$ python3 -m timeit -n 100 -s 'rr=[];tt=[];' "for i in (range(1000) for x in range(10000)): tmp = list(i); rr.append(min(tmp));tt.append(max(tmp))" 
100 loops, best of 3: 314 msec per loop

$ python3 -m timeit -n 100 "rr=[min(list(i)) for i in (range(1000) for x in range(10000))];tt=[max(list(i)) for i in (range(1000) for x in range(10000))]"
100 loops, best of 3: 413 msec per loop

もちろん、これらの場合の比較は不公平です;この例では、従来のループでは一時的な結果が保存されるため、コードと計算は同等ではありません(tmp変数を参照)。したがって、リスト内包表記は、内部操作をはるかに多く実行しています(tmp変数を2回計算しますが、25%遅くなります)。

6
toto_tico

要素がリストの場合、リスト内包が複数のリストを返す可能性があります。だから例えば:

>>> x, y = [[] for x in range(2)]
>>> x
[]
>>> y
[]
>>>

Zip関数を使ったトリックでうまくいきますが、ループでリストの結果を収集するだけであれば、実際にははるかに簡単で読みやすくなります。

1
Mariy