2011-12-04 27 views
40

2つのリストからリストのリストを実行する最も速くて洗練された方法は何ですか?タプルの代わりにリスト出力を持つジップ

私は

In [1]: a=[1,2,3,4,5,6] 

In [2]: b=[7,8,9,10,11,12] 

In [3]: zip(a,b) 
Out[3]: [(1, 7), (2, 8), (3, 9), (4, 10), (5, 11), (6, 12)] 

を持っていると私は

In [3]: some_method(a,b) 
Out[3]: [[1, 7], [2, 8], [3, 9], [4, 10], [5, 11], [6, 12]] 

私が代わりに郵便番号のマップを使用して考えていたが、一部の標準ライブラリのメソッドがある場合、私は知りませんしたいのですが最初の引数として置く。

これは私の独自の機能を定義し、マップを使用することができますが、私の質問は既に何かが実装されている場合です。 いいえも答えです。

+1

本当に**リストが必要ですか?あなたは結果と何をするつもりですか? –

+7

例はsklearnです。何度もデータをこのように整理しなければなりません。 –

答えて

52

あなたが(そのことについて、あるいはわずか2)2つの以上のリストをビュンしている場合は、読み込み可能な方法は次のようになります。

[list(a) for a in zip([1,2,3], [4,5,6], [7,8,9])] 

これは、リスト内の各要素(タプル)のリスト内包表記を使用して変換し、リストに入れる

3

私は一般的に、あなたが余分なスピードが必要な場合は、マップがわずかに速いですlambdaを使って好きですが、...

>>> a = [1, 2, 3, 4, 5] 
>>> b = [6, 7, 8, 9, 10] 
>>> c = lambda a, b: [list(c) for c in zip(a, b)] 
>>> c(a, b) 
[[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]] 

ません:

>>> d = lambda a, b: map(list, zip(a, b)) 
>>> d(a, b) 
[[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]] 

ただし、マップがunpythonicとみなされ、パフォーマンスチューニングにのみ使用する必要があります。

+3

'lambda'はここに何を追加しますか?関数を呼び出す代わりに式を書くことができます(実際には複雑ではありません)。また、関数を必要としていても、2行で痛みなく定義することができます(戻りキーが壊れているか、 。一方、 'map'は最初の引数が普通の関数(' lambda'とは対照的に)であれば完璧にうまくいきます。 – delnan

+1

彼は機能を求めました。しかし、私は同意する - 恐らく余分なラインを支払うだけで良い。マップについては、リストの理解はほとんど常に明確です。 –

+1

私は 'lambda'に' map'を勧めます。だから 'map(list、zip(a、b))'。リスト内包が少しはっきりしているかもしれませんが、地図はもっと速くなければなりません(テストされていない) – inspectorG4dget

1

これはいかがですか?

>>> def list_(*args): return list(args) 

>>> map(list_, range(5), range(9,4,-1)) 
[[0, 9], [1, 8], [2, 7], [3, 6], [4, 5]] 

あるいはさらに良い:

>>> def zip_(*args): return map(list_, *args) 
>>> zip_(range(5), range(9,4,-1)) 
[[0, 9], [1, 8], [2, 7], [3, 6], [4, 5]] 
+0

それは、ここで私がzipをやっていないし、直接リストを作成することで1つのステップを減らしているので、私より残りの部分よりも良い答えに思えます。 Awesome –

12

私はジップ機能の優雅さを愛するが、オペレータモジュールにitemgetter()関数を使用すると、はるかに高速であるように思われます。私はこれをテストするための簡単なスクリプトを書きました:

import time 
from operator import itemgetter 

list1 = list() 
list2 = list() 
origlist = list() 
for i in range (1,5000000): 
     t = (i, 2*i) 
     origlist.append(t) 

print "Using zip" 
starttime = time.time() 
list1, list2 = map(list, zip(*origlist)) 
elapsed = time.time()-starttime 
print elapsed 

print "Using itemgetter" 
starttime = time.time() 
list1 = map(itemgetter(0),origlist) 
list2 = map(itemgetter(1),origlist) 
elapsed = time.time()-starttime 
print elapsed 

私はジッパーが速くなると予想しますが、itemgetter方法は、ロングショットで勝つ:

Using zip 
6.1550450325 
Using itemgetter 
0.768098831177 
+2

これは、OPがやろうとしていることの転置です。それを反映するためにあなたの投稿を更新できますか?つまり、OPは2つのリストをリストまたは任意の数のペアに変換しています。任意の数のペアをリストのペアに変換しています。 –

+0

これはどのPythonバージョンで測定されますか? – Moberg

+0

私は覚えていませんが、それは2年以上前ですが、おそらく2.6または2.7です。コードをコピーして自分のバージョン/プラットフォームで試すことができると思います。 – kslnet

12

あなたは、ほとんどの答えを自分で持っていました。 zipの代わりにmapを使用しないでください。 mapおよびzipを使用してください。

あなたは、エレガントな、機能的なアプローチのためのジッパーと一緒にマップを使用することができます。

map(list, zip(a, b)) 

zipはタプルのリストを返します。 map(list, [...])は、リスト内の各タプルに対してlistを呼び出します。

0

リストの理解は私が推測すると非常に簡単な解決策になります。

a=[1,2,3,4,5,6] 

b=[7,8,9,10,11,12] 

x = [[i, j] for i, j in zip(a,b)] 

print(x) 

output : [[1, 7], [2, 8], [3, 9], [4, 10], [5, 11], [6, 12]] 
関連する問題