如何将元组列表转换为多个列表?

xia*_*012 90 python tuples list

假设我有一个元组列表,我想转换为多个列表.

例如,元组列表是

[(1,2),(3,4),(5,6),]
Run Code Online (Sandbox Code Playgroud)

Python中是否有任何内置函数将其转换为:

[1,3,5],[2,4,6]
Run Code Online (Sandbox Code Playgroud)

这可以是一个简单的程序.但我只是对Python中这种内置函数的存在感到好奇.

Sve*_*ach 138

内置函数zip()几乎可以满足您的需求:

>>> zip(*[(1, 2), (3, 4), (5, 6)])
[(1, 3, 5), (2, 4, 6)]
Run Code Online (Sandbox Code Playgroud)

唯一的区别是你得到元组而不是列表.您可以使用它们将它们转换为列表

map(list, zip(*[(1, 2), (3, 4), (5, 6)]))
Run Code Online (Sandbox Code Playgroud)


Cla*_*diu 39

python文档:

zip()与*运算符一起用于解压缩列表:

具体例子:

>>> zip((1,3,5),(2,4,6))
[(1, 2), (3, 4), (5, 6)]
>>> zip(*[(1, 2), (3, 4), (5, 6)])
[(1, 3, 5), (2, 4, 6)]
Run Code Online (Sandbox Code Playgroud)

或者,如果你真的想要列表:

>>> map(list, zip(*[(1, 2), (3, 4), (5, 6)]))
[[1, 3, 5], [2, 4, 6]]
Run Code Online (Sandbox Code Playgroud)


Art*_*nka 9

使用:

a = [(1,2),(3,4),(5,6),]    
b = zip(*a)
>>> [(1, 3, 5), (2, 4, 6)]
Run Code Online (Sandbox Code Playgroud)


fra*_*f95 8

尽管*zip更Pythonic,以下代码具有更好的性能:

xs, ys = [], []
for x, y in zs:
    xs.append(x)
    ys.append(y)
Run Code Online (Sandbox Code Playgroud)

另外,当原始列表zs为空时,*zip会引发,但这段代码可以正确处理。

我刚刚进行了一个快速实验,结果如下:

Using *zip:     1.54701614s
Using append:   0.52687597s
Run Code Online (Sandbox Code Playgroud)

多次运行它,append比 ! 快 3 倍 - 4 倍zip!测试脚本在这里:

#!/usr/bin/env python3
import time

N = 2000000
xs = list(range(1, N))
ys = list(range(N+1, N*2))
zs = list(zip(xs, ys))

t1 = time.time()

xs_, ys_ = zip(*zs)
print(len(xs_), len(ys_))

t2 = time.time()

xs_, ys_ = [], []
for x, y in zs:
    xs_.append(x)
    ys_.append(y)
print(len(xs_), len(ys_))

t3 = time.time()

print('Using *zip:\t{:.8f}s'.format(t2 - t1))
print('Using append:\t{:.8f}s'.format(t3 - t2))
Run Code Online (Sandbox Code Playgroud)

我的Python版本:

Python 3.6.3 (default, Oct 24 2017, 12:18:40)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Run Code Online (Sandbox Code Playgroud)


Bal*_*ckk 7

Franklsf95 在他的答案中追求性能并选择list.append(),但它们并不是最佳的。

添加列表理解,我最终得到以下结果:

def t1(zs):
    xs, ys = zip(*zs)
    return xs, ys

def t2(zs):
    xs, ys = [], []
    for x, y in zs:
        xs.append(x)
        ys.append(y)
    return xs, ys

def t3(zs):
    xs, ys = [x for x, y in zs], [y for x, y in zs]
    return xs, ys

if __name__ == '__main__':
    from timeit import timeit
    setup_string='''\
N = 2000000
xs = list(range(1, N))
ys = list(range(N+1, N*2))
zs = list(zip(xs, ys))
from __main__ import t1, t2, t3
'''
    print(f'zip:\t\t{timeit('t1(zs)', setup=setup_string, number=1000)}')
    print(f'append:\t\t{timeit('t2(zs)', setup=setup_string, number=1000)}')
    print(f'list comp:\t{timeit('t3(zs)', setup=setup_string, number=1000)}')
Run Code Online (Sandbox Code Playgroud)

结果如下:

zip:            122.11585397789766
append:         356.44876132614047
list comp:      144.637765085659
Run Code Online (Sandbox Code Playgroud)

因此,如果您追求性能,您可能应该使用zip()列表推导式,尽管列表推导式也相差不远。相比之下,性能append实际上相当差。