Qual é a maneira mais rápida e elegante de fazer 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 map em vez de 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 map, minha dúvida é se já existe algo implementado. Não também é uma resposta.
Respostas:
Se você estiver compactando mais de 2 listas (ou mesmo apenas 2, nesse caso), uma forma legível seria:
[list(a) for a in zip([1,2,3], [4,5,6], [7,8,9])]
Isso usa compreensões de lista e converte cada elemento da lista (tuplas) em listas.
fonte
Você quase teve a resposta sozinho. Não use em
map
vez dezip
. Usemap
ANDzip
.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, [...])
chamalist
cada tupla da lista.list(map([...])
transforma o objeto do mapa em uma lista legível.fonte
generator
impõe o custo do dobrolist
aqui.Adoro a elegância da função zip, mas usar a função itemgetter () no módulo do operador parece ser muito mais rápido. 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 vence por muito tempo:
Using zip 6.1550450325 Using itemgetter 0.768098831177
fonte
zip
cria uma lista real. Isso retarda as coisas. Tente substituirzip
poritertools.izip
então.list1 = [x[0] for x in origlist]
funciona tão bem quantolist1 = map(itemgetter(0), origlist)
.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 impotônico e deve ser usado apenas para ajuste de desempenho.
fonte
lambda
adiciona aqui? Pode-se apenas escrever a expressão em vez de chamar uma função (não é realmente complicado), e mesmo se alguém quiser uma função para ela, ela pode ser definida sem dor em duas linhas (uma se sua tecla de retorno estiver quebrada ou você for louco) .map
por outro lado, está perfeitamente bem se o primeiro argumento for uma função simples (em oposição a alambda
).map
maislambda
. entãomap(list, zip(a,b))
. As compreensões da lista podem ser um pouco mais claras, mas o mapa deve ser mais rápido (não testado)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]]
fonte
Usando numpy
A definição de elegância pode ser bastante questionável, mas se você estiver trabalhando com
numpy
a criação de um array e sua conversão para lista (se necessário ...) pode ser muito prática, embora não seja tão eficiente em comparação com o uso damap
função ou da compreensão de 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, pule a
zip
função que você pode usar diretamentenp.dstack
:np.dstack((a,b))[0].tolist()
fonte
A compreensão de listas 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]]
fonte