Antworten:
Wie wäre es mit
map(list, zip(*l))
--> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Für Python 3.x können Benutzer verwenden
list(map(list, zip(*l)))
Erläuterung:
Es gibt zwei Dinge, die wir wissen müssen, um zu verstehen, was los ist:
zip(*iterables)
Dies bedeutet, zip
dass eine beliebige Anzahl von Argumenten erwartet wird, von denen jedes iterierbar sein muss. ZB zip([1, 2], [3, 4], [5, 6])
.args
, f(*args)
rufen , f
so dass jedes Element in args
einem getrenntes Positions Argument f
.Auf die Eingabe aus der Frage zurückzukommen l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
, zip(*l)
wäre gleichbedeutend mit zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
. Der Rest stellt nur sicher, dass das Ergebnis eine Liste von Listen anstelle einer Liste von Tupeln ist.
list(zip(*l))
funktioniert sogar richtig in Python 3.
zip(*l)
in Python 2), aber Sie erhalten eine Liste von Tupeln, keine Liste von Listen. Natürlich list(list(it))
ist immer das Gleiche wie list(it)
.
Eine Möglichkeit ist die NumPy-Transponierung. Für eine Liste gilt Folgendes:
>>> import numpy as np
>>> np.array(a).T.tolist()
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Oder eine andere ohne Reißverschluss:
>>> map(list,map(None,*a))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
map
dass ich das tun kann. Hier ist eine leichte Verfeinerung, die jedoch keine zwei Anrufe erfordert:map(lambda *a: list(a), *l)
map(None, ...)
scheint nicht für Py3 zu funktionieren. Der Generator wird erstellt, next()
löst jedoch sofort einen Fehler aus : TypeError: 'NoneType' object is not callable
.
Entsprechend Jenas Lösung:
>>> l=[[1,2,3],[4,5,6],[7,8,9]]
>>> [list(i) for i in zip(*l)]
... [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
map()
ist diese Lösung diejenige, die am meisten im Python-Geist ist ...
Nur zum Spaß, gültige Rechtecke und unter der Annahme, dass m [0] existiert
>>> m = [[1,2,3],[4,5,6],[7,8,9]]
>>> [[row[i] for row in m] for i in range(len(m[0]))]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
[[j[i] for j in l] for i in range(len(l[0]))]
. Natürlich müssen Sie sicherstellen, dass die Liste l
nicht leer ist.
Die Methoden 1 und 2 funktionieren in Python 2 oder 3 und in unregelmäßigen, rechteckigen 2D-Listen. Das bedeutet, dass die inneren Listen nicht die gleiche Länge haben müssen (zackig) oder wie die äußeren Listen (rechteckig). Die anderen Methoden sind kompliziert.
import itertools
import six
list_list = [[1,2,3], [4,5,6, 6.1, 6.2, 6.3], [7,8,9]]
map()
,zip_longest()
>>> list(map(list, six.moves.zip_longest(*list_list, fillvalue='-')))
[[1, 4, 7], [2, 5, 8], [3, 6, 9], ['-', 6.1, '-'], ['-', 6.2, '-'], ['-', 6.3, '-']]
six.moves.zip_longest()
wird
itertools.izip_longest()
in Python 2itertools.zip_longest()
in Python 3Der Standardfüllwert ist None
. Dank der Antwort von @ jena , wo map()
die inneren Tupel in Listen geändert werden. Hier werden Iteratoren in Listen umgewandelt. Vielen Dank an die Kommentare von @ Oregano und @ badp .
Übergeben Sie in Python 3 das Ergebnis list()
, um dieselbe 2D-Liste wie in Methode 2 zu erhalten.
zip_longest()
>>> [list(row) for row in six.moves.zip_longest(*list_list, fillvalue='-')]
[[1, 4, 7], [2, 5, 8], [3, 6, 9], ['-', 6.1, '-'], ['-', 6.2, '-'], ['-', 6.3, '-']]
Die @ inspectorG4dget-Alternative .
map()
of map()
- in Python 3.6 gebrochen>>> map(list, map(None, *list_list))
[[1, 4, 7], [2, 5, 8], [3, 6, 9], [None, 6.1, None], [None, 6.2, None], [None, 6.3, None]]
Diese außerordentlich kompakte zweite Alternative von @SiggyF funktioniert mit zerlumpten 2D-Listen, im Gegensatz zu seinem ersten Code, der numpy verwendet, um zerlumpte Listen zu transponieren und zu durchlaufen. Aber keiner muss der Füllwert sein. (Nein, das an die innere Map () übergebene None ist nicht der Füllwert. Dies bedeutet, dass keine Funktion zum Verarbeiten jeder Spalte vorhanden ist. Die Spalten werden nur an die äußere Map () übergeben, die sie von Tupeln in Listen konvertiert.
Irgendwo in Python 3 wurde map()
dieser Missbrauch nicht mehr ertragen: Der erste Parameter kann nicht None sein, und zerlumpte Iteratoren werden nur auf die kürzeste Zeit abgeschnitten. Die anderen Methoden funktionieren weiterhin, da dies nur für die innere Map () gilt.
map()
von map()
überarbeitet>>> list(map(list, map(lambda *args: args, *list_list)))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]] // Python 2.7
[[1, 4, 7], [2, 5, 8], [3, 6, 9], [None, 6.1, None], [None, 6.2, None], [None, 6.3, None]] // 3.6+
Leider werden die unregelmäßigen Zeilen in Python 3 NICHT zu unregelmäßigen Spalten, sondern nur abgeschnitten. Boo hoo Fortschritt.
solution1 = map(list, zip(*l))
solution2 = [list(i) for i in zip(*l)]
solution3 = []
for i in zip(*l):
solution3.append((list(i)))
print(*solution1)
print(*solution2)
print(*solution3)
# [1, 4, 7], [2, 5, 8], [3, 6, 9]
Vielleicht nicht die eleganteste Lösung, aber hier ist eine Lösung mit verschachtelten while-Schleifen:
def transpose(lst):
newlist = []
i = 0
while i < len(lst):
j = 0
colvec = []
while j < len(lst):
colvec.append(lst[j][i])
j = j + 1
newlist.append(colvec)
i = i + 1
return newlist
import numpy as np
r = list(map(list, np.transpose(l)))
more_itertools.unzip()
ist leicht zu lesen und funktioniert auch mit Generatoren.
import more_itertools
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
r = more_itertools.unzip(l) # a tuple of generators.
r = list(map(list, r)) # a list of lists
oder gleichwertig
import more_itertools
l = more_itertools.chunked(range(1,10), 3)
r = more_itertools.unzip(l) # a tuple of generators.
r = list(map(list, r)) # a list of lists
Hier ist eine Lösung zum Transponieren einer Liste von Listen, die nicht unbedingt quadratisch ist:
maxCol = len(l[0])
for row in l:
rowLength = len(row)
if rowLength > maxCol:
maxCol = rowLength
lTrans = []
for colIndex in range(maxCol):
lTrans.append([])
for row in l:
if colIndex < len(row):
lTrans[colIndex].append(row[colIndex])
#Import functions from library
from numpy import size, array
#Transpose a 2D list
def transpose_list_2d(list_in_mat):
list_out_mat = []
array_in_mat = array(list_in_mat)
array_out_mat = array_in_mat.T
nb_lines = size(array_out_mat, 0)
for i_line_out in range(0, nb_lines):
array_out_line = array_out_mat[i_line_out]
list_out_line = list(array_out_line)
list_out_mat.append(list_out_line)
return list_out_mat
l
Größe nicht gleichmäßig ist (z. B. sind einige Zeilen kürzer als andere),zip
wird dies nicht kompensiert und stattdessen werden Zeilen aus der Ausgabe entfernt. Sol=[[1,2],[3,4],[5]]
gibt es dir[[1,3,5]]
.