タプルの代わりにリスト出力を使用したZip


95

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を使用することを考えていましたが、最初の引数として配置する標準ライブラリメソッドがあるかどうかはわかりません。

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


1
さて、あなたは本当にリストが必要ですか?結果をどうしますか?
Karl Knechtel 2011

14
例としてはsklearnがあり、データはこの方法で何度も整理する必要があります。
tumultous_rooster 2013

回答:


103

2つ以上のリスト(さらに言えば2つだけ)を圧縮する場合、読みやすい方法は次のようになります。

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

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


55

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

マップをzipと一緒に使用して、エレガントで機能的なアプローチをとることができます。

list(map(list, zip(a, b)))

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


python 3コレクション操作を返すという不幸な決定generatorは、listここでダブルのコストを課します。
StephenBoesch

15

私はzip関数の優雅さが大好きですが、演算子モジュールで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

2
これは、OPが行おうとしていることの転置です。それを反映するように投稿を更新できますか?つまり、OPは2つのリストをリストまたは任意の数のペアに変換しています。任意の数のペアをリストのペアに変換しています。
狂牛病の物理学者

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

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

2
python2zipは実際のリストを作成します。それは物事を遅くします。それで置き換えzipてみてくださいitertools.izip
ジャン=フランソワ・ファーブル

Python 3.5では、zipは3.5秒、itemgetterは0.10秒かかります。リスト内包表記が好きな人にとっては、とlist1 = [x[0] for x in origlist]同じように機能しlist1 = map(itemgetter(0), origlist)ます。
エリアスストレール2018年

3

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

>>> 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は非Pythonであると見なされ、パフォーマンスチューニングにのみ使用する必要があります。


4
lambdaここに何を追加しますか?関数を呼び出す代わりに式を書くことができ(実際には複雑ではありません)、関数が必要な場合でも、2行で簡単に定義できます(1つはリターンキーが壊れているか、正気でない場合)。 。map一方、最初の引数が(ではなくlambda)単純な関数である場合は、まったく問題ありません。

1
さて彼は機能を求めました。しかし、私は同意します-おそらく余分な行を支払うだけの方が良いでしょう。地図に関しては、リスト内包表記はほとんどの場合より明確であると思います。
Ceasar Bautista 2011

1
私はmap以上をお勧めしlambdaます。そうmap(list, zip(a,b))。リスト内包表記は少し明確かもしれませんが、マップはより高速である必要があります(テストされていません)
inspectorG4dget

つまり、OPに速度が必要な場合は、マップが最適です。しかし、一般的に、そして特にPythonでは、速度よりも読みやすさを強調します(そうでなければ、時期尚早の最適化に没頭します)。
Ceasar Bautista 2011

3

これはどう?

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

ここでは、zipを実行せずにリストを直接作成することで、1つのステップを削減しているため、これは他の部分よりも良い答えのように思えます。素晴らしい
Akshay Hazari 2015年

2

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

リスト内包表記は、私が推測する非常に単純な解決策になるでしょう。

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]]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.