7

重複の可能性:
Python の転置/解凍関数

シーケンスのリストがあり、各シーケンスには 2 つの項目があります。これを2つのリストに変えたいと思います。

catalog = [('abc', '123'), ('foo', '456'), ('bar', '789'), ('test', '1337')]

今、私はちょうどこれをやっています:

names = []
vals = []

for product in catalog:
        names.append(product[0])
        vals.append(product[1])

print (names)
print (vals)

2 つのリストを出力し、問題なく動作します。

['abc', 'foo', 'bar', 'test']
['123', '456', '789', '1337']

これを行うための、よりきちんとした、より「pythonic」な方法はありますか? それとも、持っているものに固執する必要がありますか?プログラミング スタイルに関する修正やフィードバックは大歓迎です。私は初心者で、ベスト プラクティスを学ぼうとしています。

4

2 に答える 2

14
>>> catalog = [('abc', '123'), ('foo', '456'), ('bar', '789'), ('test', '1337')]
>>> names, vals = zip(*catalog)
>>> names
('abc', 'foo', 'bar', 'test')
>>> vals
('123', '456', '789', '1337')

ここでの*catalog構文は、引数リストの解凍zip(*catalog)と呼ばれ、呼び出しに変換されますzip(catalog[0], catalog[1], catalog[2], ...)

組み込み関数はzip()反復可能オブジェクトをインデックスでグループ化するため、上記のように2要素タプルの束を渡すと、最初のタプルにからの各タプルの最初の要素がcatalog含まれ、2番目のタプルにからの各タプルからの2番目の要素catalog

クイックタイムテストではzip()、1,000,000ペアでテストしたときに、バージョンがループアプローチよりも優れています。

In [1]: catalog = [(i, i+1) for i in range(1000000)]

In [2]: def with_zip():
   ...:     return zip(*catalog)
   ...: 

In [3]: def without_zip():
   ...:     names, vals = [], []
   ...:     for name, val in catalog:
   ...:         names.append(name)
   ...:         vals.append(val)
   ...:     return names, vals
   ...: 

In [4]: %timeit with_zip()
1 loops, best of 3: 176 ms per loop

In [5]: %timeit without_zip()
1 loops, best of 3: 250 ms per loop
于 2012-12-17T18:51:38.577 に答える
3

確かに、これを使用してください:

lst = [('abc', '123'), ('foo', '456'), ('bar', '789'), ('test', '1337')]
tup1, tup2 = zip(*lst)

上記は、要素を持つタプルのペアを返します。リストが必要な場合は、次を使用してください。

lst = [('abc', '123'), ('foo', '456'), ('bar', '789'), ('test', '1337')]
lst1, lst2 = map(list, zip(*lst))
于 2012-12-17T18:53:35.387 に答える