Vamos levar:
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
O resultado que estou procurando é
r = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
e não
r = [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
Muito apreciado
E se
map(list, zip(*l))
--> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Para python 3.x, os usuários podem usar
list(map(list, zip(*l)))
Explicação:
Há duas coisas que precisamos saber para entender o que está acontecendo:
zip(*iterables)
isso significa que zip
espera um número arbitrário de argumentos, cada um dos quais deve ser iterável. Por exemplo zip([1, 2], [3, 4], [5, 6])
.args
, f(*args)
chamará f
tal que cada elemento em args
seja um argumento posicional separado de f
.Voltando à entrada da pergunta l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
, zip(*l)
seria equivalente a zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
. O resto é apenas garantir que o resultado seja uma lista de listas em vez de uma lista de tuplas.
l
não é dimensionada de maneira uniforme (por exemplo, algumas linhas são mais curtas do que outros),zip
será não compensá-lo e, em vez corta fora as linhas da saída. Entãol=[[1,2],[3,4],[5]]
te dá[[1,3,5]]
.itertools
funçãozip_longest()
funciona com listas desiguais. Veja DOCSlist(zip(*l))
funciona corretamente em Python 3.zip(*l)
no Python 2), mas você obtém uma lista de tuplas, não uma lista de listas. Claro,list(list(it))
é sempre a mesma coisa quelist(it)
.Uma maneira de fazer isso é com a transposição do NumPy. Para uma lista, a:
Ou outro sem zip:
fonte
map
poderia fazer isso. Aqui está um leve refinamento que não requer duas chamadas, no entanto:map(lambda *a: list(a), *l)
map(None, ...)
parece não funcionar para o Py3. O gerador é criada, masnext()
gera um erro imediatamente:TypeError: 'NoneType' object is not callable
.Equivalentemente à solução de Jena:
fonte
map()
, esta solução é aquela que é a mais no espírito Python ...apenas por diversão, retângulos válidos e assumindo que m [0] existe
fonte
[[j[i] for j in l] for i in range(len(l[0]))]
. Obviamente, você precisa ter certeza de que a listal
não está vazia.Os métodos 1 e 2 funcionam em Python 2 ou 3 e funcionam em retângulos irregulares listas 2D . Isso significa que as listas internas não precisam ter os mesmos comprimentos entre si (irregulares) ou como as listas externas (retangulares). Os outros métodos, bem, são complicados.
a configuração
método 1 -
map()
,zip_longest()
six.moves.zip_longest()
torna-seitertools.izip_longest()
em Python 2itertools.zip_longest()
em Python 3O valor de preenchimento padrão é
None
. Graças à resposta de @ jena , ondemap()
está alterando as tuplas internas para listas. Aqui está transformando iteradores em listas. Graças a @ e do Oregano de @ badp comentários .No Python 3, passe o resultado
list()
para obter a mesma lista 2D do método 2.método 2 - compreensão da lista,
zip_longest()
A alternativa @ inspectorG4dget .
método 3 -
map()
ofmap()
- quebrado em Python 3.6Essa segunda alternativa extraordinariamente compacta do @SiggyF funciona com listas 2D irregulares, ao contrário de seu primeiro código, que usa numpy para transpor e passar por listas irregulares. Mas Nenhum deve ser o valor de preenchimento. (Não, o None passado para o mapa interno () não é o valor de preenchimento. Isso significa que não há função para processar cada coluna. As colunas são passadas apenas para o mapa externo () que as converte de tuplas em listas.
Em algum lugar do Python 3,
map()
parou de tolerar todo esse abuso: o primeiro parâmetro não pode ser None e os iteradores irregulares são truncados no menor tempo possível. Os outros métodos ainda funcionam porque isso se aplica apenas ao mapa interno ().método 4 -
map()
demap()
revisitadoInfelizmente, as linhas irregulares NÃO se tornam colunas irregulares no Python 3, elas são apenas truncadas. Boo hoo progresso.
fonte
Três opções para escolher:
1. Mapa com Zip
2. Compreensão da lista
3. Para loop anexado
E para visualizar os resultados:
fonte
Talvez não seja a solução mais elegante, mas aqui está uma solução usando loops while aninhados:
fonte
fonte
more_itertools.unzip()
é fácil de ler e também funciona com geradores.ou equivalente
fonte
Aqui está uma solução para transpor uma lista de listas que não é necessariamente quadrada:
fonte
fonte