Nehmen wir an:
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Das Ergebnis, das ich suche, ist
r = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
und nicht
r = [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
Nehmen wir an:
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Das Ergebnis, das ich suche, ist
r = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
und nicht
r = [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
Python 3:
# short circuits at shortest nested list if table is jagged:
list(map(list, zip(*l)))
# discards no data if jagged and fills short nested lists with None
list(map(list, itertools.zip_longest(*l, fillvalue=None)))
Python 2:
map(list, zip(*l))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Erläuterung:
Es gibt zwei Dinge, die wir wissen müssen, um zu verstehen, was hier vor sich geht:
zip(*iterables)
Dies bedeutet zip
erwartet eine beliebige Anzahl von Argumenten, von denen jedes iterierbar sein muss. z.B. zip([1, 2], [3, 4], [5, 6])
.args
, f(*args)
wird anrufen f
so dass jedes Element in args
ist ein separates Positionsargument von f
.itertools.zip_longest
verwirft keine Daten, wenn die Anzahl der Elemente der verschachtelten Listen nicht gleich ist (homogen), und füllt stattdessen die kürzeren verschachtelten Listen aus entonces macht sie zu.Um auf den Input 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 besteht darin, sicherzustellen, dass das Ergebnis eine Liste von Listen und nicht eine Liste von Tupeln ist.
Eine Möglichkeit, dies zu tun, ist mit NumPy transponieren . Für eine Liste, a:
>>> 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]]
Die Methoden 1 und 2 funktionieren in Python 2 oder 3, und sie funktionieren auf zerklüftet, rechteckig 2D-Listen. Das bedeutet, dass die inneren Listen nicht die gleiche Länge haben müssen wie die äußeren Listen (rechteckig) oder wie die inneren Listen untereinander (zackig). Die anderen Methoden, nun ja, es ist 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 @jena's Antwort donde map()
ist die Umwandlung der inneren Tupel in Listen. Hier werden Iteratoren in Listen umgewandelt. Dank @Oregano's und @badp's Kommentare .
In Python 3 übergeben Sie das Ergebnis durch list()
um die gleiche 2D-Liste wie bei 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, '-']]
En @inspectorG4dget alternativ .
map()
de map()
- gebrochen in Python 3.6>>> 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 @SiggyF zweite Alternative funktioniert mit zackigen 2D-Listen, im Gegensatz zu seinem ersten Code, der Numpy zum Transponieren und Durchlaufen von zackigen Listen verwendet. Aber None muss der Füllwert sein. (Nein, das an die innere map() übergebene None ist nicht der Füllwert. Es bedeutet, dass es keine Funktion gibt, die jede Spalte verarbeitet. Die Spalten werden einfach an die äußere map() weitergegeben, die sie von Tupeln in Listen umwandelt).
Irgendwo in Python 3, map()
hat aufgehört, diesen Missbrauch zu dulden: Der erste Parameter kann nicht None sein, und die lückenhaften Iteratoren werden einfach auf den kürzesten Wert gekürzt. Die anderen Methoden funktionieren weiterhin, da dies nur für die innere map() gilt.
map()
de 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 ausgefransten Zeilen in Python 3 NICHT zu ausgefransten Spalten, sie werden nur abgeschnitten. Boo hoo Fortschritt.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.