2011-12-04 9 views
40

¿Cuál es la forma más rápida y elegante de hacer una lista de listas de dos listas?Código postal con salida de lista en lugar de tupla

que tienen

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

y me gustaría tener

In [3]: some_method(a,b) 
Out[3]: [[1, 7], [2, 8], [3, 9], [4, 10], [5, 11], [6, 12]] 

Estaba pensando en el mapa en lugar de postal, pero no sé si hay algún método librería estándar para poner como primer argumento.

Puedo definir mi propia función para esto, y usar el mapa, mi pregunta es si ya se ha implementado algo. No es también una respuesta.

+1

Bueno, ¿realmente ** necesita ** listas? ¿Qué vas a hacer con los resultados? –

+7

Un ejemplo sería sklearn, donde muchas veces los datos deben organizarse de esta manera. –

Respuesta

52

Si va a pasar con velocidad de más de 2 listas (o incluso sólo 2, para el caso), de manera legible sería:

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

Esto utiliza las listas por comprensión y convierte cada elemento de la lista (tuplas) en listas.

3

lo general no me gusta usar lambda, pero ...

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

Si necesita la velocidad extra, un mapa es un poco más rápido:

>>> d = lambda a, b: map(list, zip(a, b)) 
>>> d(a, b) 
[[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]] 

Sin embargo, se considera mapa y unpythonic solo debe usarse para ajustar el rendimiento.

+3

¿Qué significa 'lambda' agregar aquí? Uno puede simplemente escribir la expresión en lugar de llamar a una función (en realidad no es complicado), e incluso si uno quiere una función para ella, se puede definir sin dolor en dos líneas (una si la tecla de retorno está rota o estás loco). . 'map' por otro lado está perfectamente bien si el primer argumento sería una función simple (en oposición a un' lambda'). – delnan

+1

Bueno, él pidió una función. Pero estoy de acuerdo, probablemente sea mejor pagar la línea adicional. En cuanto al mapa, creo que las listas de comprensión son casi siempre más claras. –

+1

Yo recomendaría 'map' sobre' lambda'. entonces 'map (list, zip (a, b))'. La comprensión de las listas puede ser un poco más clara, pero el mapa debe ser más rápido (no probado) – inspectorG4dget

1

¿Qué tal esto?

>>> def list_(*args): return list(args) 

>>> map(list_, range(5), range(9,4,-1)) 
[[0, 9], [1, 8], [2, 7], [3, 6], [4, 5]] 

O aún mejor:

>>> def zip_(*args): return map(list_, *args) 
>>> zip_(range(5), range(9,4,-1)) 
[[0, 9], [1, 8], [2, 7], [3, 6], [4, 5]] 
+0

Eso me parece una mejor respuesta que el resto ya que aquí estamos reduciendo un paso al no hacer un zip y crear directamente una lista. Impresionante –

12

Me encanta la elegancia de la función zip, pero utilizando el itemgetter() en el módulo de mando parece ser mucho más rápido. Me escribió un script sencillo para probar esto:

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 

que esperaba postal para ser más rápido, pero el método itemgetter gana por asomo:

Using zip 
6.1550450325 
Using itemgetter 
0.768098831177 
+2

Esto es una transposición de lo que el OP está tratando de hacer. ¿Podrías actualizar tu publicación para reflejar eso? Es decir, OP está convirtiendo dos listas en listas o en un número arbitrario de pares. Está convirtiendo un número arbitrario de pares en un par de listas. –

+0

¿Con qué versión de python se mide esto? – Moberg

+0

No recuerdo, fue hace más de dos años, pero muy probablemente 2.6 o 2.7. Me imagino que puedes copiar el código y probarlo en tu propia versión/plataforma. – kslnet

12

Casi tenía la respuesta usted mismo. No use map en lugar de zip. Use mapYzip.

Puede utilizar mapa junto con cremallera para un enfoque elegante, funcional:

map(list, zip(a, b)) 

zip devuelve una lista de tuplas. map(list, [...]) llama a list en cada tupla de la lista.

0

La comprensión de la lista sería una solución muy simple, supongo.

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