ti-enxame.com

Compacte com saída de lista em vez de tupla

Qual é a maneira mais rápida e elegante de fazer listas de listas de duas listas?

Eu tenho

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

E eu gostaria de ter

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

Eu estava pensando em usar o mapa em vez do Zip, mas não sei se existe algum método de biblioteca padrão para colocar como primeiro argumento.

Eu posso definir minha própria função para isso e usar o mapa, minha pergunta é se já existe alguma coisa implementada. Não também é uma resposta.

53
Jan Vorcak

Se você estiver zipando mais de 2 listas (ou mesmo apenas 2), uma maneira legível seria:

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

Isso usa as compreensões da lista e converte cada elemento da lista (tuplas) em listas.

59
D K

Você quase teve a resposta sozinho. Não use map em vez de Zip. Use mapEZip.

Você pode usar o mapa junto com o Zip para uma abordagem elegante e funcional:

list(map(list, Zip(a, b)))

Zip retorna uma lista de tuplas. map(list, [...]) chama list em cada Tuple na lista. list(map([...]) transforma o objeto do mapa em uma lista legível.

27
Eldamir

Eu amo a elegância da função Zip, mas usar a função itemgetter () no módulo do operador parece ser muito mais rápido. Eu escrevi um script simples para testar isso:

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

Eu esperava que o Zip fosse mais rápido, mas o método itemgetter ganha de longe:

Using Zip
6.1550450325
Using itemgetter
0.768098831177
13
kslnet

Que tal agora?

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

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

Ou melhor ainda:

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

Eu geralmente não gosto de usar lambda, mas ...

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

Se você precisar de velocidade extra, o mapa é um pouco mais rápido:

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

No entanto, o mapa é considerado não-patético e deve ser usado apenas para ajuste de desempenho.

3
Ceasar Bautista

Usando numpy

A definição de elegância pode ser bastante questionável, mas se você estiver trabalhando com numpy a criação de uma matriz e sua conversão para lista (se necessário ...) pode ser muito prática, embora não seja tão eficiente comparada usando a função map ou a compreensão da lista .

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

Caso contrário, pular a função Zip você pode usar diretamente np.dstack :

np.dstack((a,b))[0].tolist()
0
G M

A compreensão da lista seria uma solução muito simples, eu acho.

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