web-dev-qa-db-ja.com

タプルの代わりにリスト出力を含むZip

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]]

Zipの代わりにmapを使用することを考えていましたが、最初の引数として配置する標準ライブラリメソッドがあるかどうかわかりません。

このために独自の関数を定義し、マップを使用できます。私の質問は、既に実装されているものがあるかどうかです。 Noも答えです。

63
Jan Vorcak

3つ以上のリスト(または2つだけ)を圧縮する場合、読みやすい方法は次のとおりです。

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

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

69
D K

あなたはほとんど自分で答えがありました。 mapの代わりにZipを使用しないでください。 map[〜#〜] and [〜#〜]Zipを使用します。

洗練された機能的なアプローチのために、Zipとともにmapを使用できます。

_list(map(list, Zip(a, b)))
_

Zipは、タプルのリストを返します。 map(list, [...])は、リスト内の各タプルでlistを呼び出します。 list(map([...])は、マップオブジェクトを読み取り可能なリストに変換します。

33
Eldamir

Zip関数のエレガントさが気に入っていますが、operatorモジュールで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

Zipはより高速になると予想していましたが、itemgetterメソッドはロングショットで勝ちます。

Using Zip
6.1550450325
Using itemgetter
0.768098831177
14
kslnet

これはどう?

>>> 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]]
3
Broseph

私は一般的にラムダを使うのが好きではありませんが、...

>>> 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]]

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

3
Ceasar Bautista

Numpyを使用する

エレガンスの定義は非常に疑わしい場合がありますが、numpyを使用している場合、配列の作成とそのリストへの変換(必要な場合)は、map関数またはリスト内包表記。

import numpy as np 
a = b = range(10)
zipped = Zip(a,b)
result = np.array(zipped).tolist()
Out: [[0, 0],
 [1, 1],
 [2, 2],
 [3, 3],
 [4, 4],
 [5, 5],
 [6, 6],
 [7, 7],
 [8, 8],
 [9, 9]]

それ以外の場合は、直接使用できるZip関数をスキップします np.dstack

np.dstack((a,b))[0].tolist()
1
G M

リストの理解は、私が推測する非常に簡単な解決策でしょう。

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]]
0
axai_m