¿Cómo convertir la lista de tuplas a múltiples listas?

Supongamos que tengo una lista de tuplas y quiero convertirlas a varias listas.

Por ejemplo, la lista de tuplas es

[(1,2),(3,4),(5,6),] 

¿Hay alguna función incorporada en Python que la convierta a:

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

Este puede ser un progtwig simple. Pero solo siento curiosidad por la existencia de dicha función incorporada en Python.

La función incorporada zip() casi hará lo que quieras:

 >>> zip(*[(1, 2), (3, 4), (5, 6)]) [(1, 3, 5), (2, 4, 6)] 

La única diferencia es que obtienes tuplas en lugar de listas. Puedes convertirlos a listas usando

 map(list, zip(*[(1, 2), (3, 4), (5, 6)])) 

De los documentos de python :

zip () junto con el operador * se puede usar para descomprimir una lista:

Ejemplo especifico:

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

O, si realmente quieres listas:

 >>> map(list, zip(*[(1, 2), (3, 4), (5, 6)])) [[1, 3, 5], [2, 4, 6]] 

Utilizar:

 a = [(1,2),(3,4),(5,6),] b = zip(*a) >>> [(1, 3, 5), (2, 4, 6)] 

franklsf95 busca el rendimiento en su respuesta y opta por list.append() , pero no son óptimos.

Agregando listas de comprensión, terminé con lo siguiente:

 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)}') 

Esto dio el resultado:

 zip: 122.11585397789766 append: 356.44876132614047 list comp: 144.637765085659 

Entonces, si está después del rendimiento, probablemente debería usar zip() aunque las comprensiones de la lista no están demasiado lejos. El rendimiento de la aplicación es bastante pobre en comparación.

Agregando a la respuesta de Claudiu y Claudiu y como el mapa debe importarse de itertools en python 3, también se usa una lista de comprensión como:

 [[*x] for x in zip(*[(1,2),(3,4),(5,6)])] >>> [[1, 3, 5], [2, 4, 6]] 

A pesar de que *zip es más Pythonic, el siguiente código tiene un rendimiento mucho mejor:

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

Además, cuando la lista original zs está vacía, *zip boostá, pero este código se puede manejar correctamente.

Acabo de realizar un experimento rápido, y aquí está el resultado:

 Using *zip: 1.54701614s Using append: 0.52687597s 

¡Al ejecutarlo varias veces, el append es 3x – 4x más rápido que zip ! El script de prueba está aquí:

 #!/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)) 

Mi versión de 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.