Weźmy:
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Wynik, którego szukam, to
r = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
i nie
r = [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
Bardzo mile widziane
Co powiesz na
map(list, zip(*l))
--> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
W przypadku python 3.x użytkownicy mogą korzystać
list(map(list, zip(*l)))
Wyjaśnienie:
Są dwie rzeczy, które musimy wiedzieć, aby zrozumieć, co się dzieje:
zip(*iterables)
Oznacza to, zip
że oczekuje dowolnej liczby argumentów, z których każdy musi być iterowalny. Np zip([1, 2], [3, 4], [5, 6])
.args
, f(*args)
wywoła f
takie, że każdy element args
jest osobnym argumentem pozycyjnym f
.Wracając do danych wejściowych z pytania l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
, zip(*l)
byłoby to równoważne z zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
. Reszta to tylko upewnienie się, że wynikiem będzie lista list zamiast listy krotek.
l
nie jest równomiernie wielkości (powiedzmy, niektóre wiersze są krótsze niż w innych),zip
będzie nie zrekompensować to i zamiast posiekać z dala wiersze z wyjścia. Więcl=[[1,2],[3,4],[5]]
daje[[1,3,5]]
.itertools
funkcjazip_longest()
działa z nierównymi listami. Zobacz DOCSlist(zip(*l))
działa poprawnie w Pythonie 3.zip(*l)
w Pythonie 2), ale dostajesz listę krotek, a nie listę list. Oczywiścielist(list(it))
zawsze jest to samo, colist(it)
.Jednym ze sposobów jest transpozycja NumPy. W przypadku listy:
Lub inny bez zip:
źródło
map
, że mogę to zrobić. Oto niewielkie udoskonalenie, które nie wymaga 2 połączeń:map(lambda *a: list(a), *l)
map(None, ...)
wydaje się nie działać dla Py3. Generator jest tworzony, alenext()
natychmiast podnosi błąd:TypeError: 'NoneType' object is not callable
.Równoważnie z rozwiązaniem Jeny:
źródło
map()
, to rozwiązanie jest najbardziej w duchu Pythona ...tylko dla zabawy, prawidłowe prostokąty i przy założeniu, że istnieje m [0]
źródło
[[j[i] for j in l] for i in range(len(l[0]))]
. Oczywiście musisz upewnić się, że listal
nie jest pusta.Metody 1 i 2 działają w języku Python 2 lub 3 i działają na nierównych, prostokątnych listach 2D. Oznacza to, że listy wewnętrzne nie muszą mieć takich samych długości (nierówne) ani zewnętrznych (prostokątne). Inne metody są skomplikowane.
ustawić
metoda 1 -
map()
,zip_longest()
six.moves.zip_longest()
staje sięitertools.izip_longest()
w Python 2itertools.zip_longest()
w Python 3Domyślna wartość wypełnienia to
None
. Dzięki @ Jeny odpowiedź , gdziemap()
zmienia wewnętrzne krotki do list. Tutaj zamienia iteratory w listy. Dzięki komentarzom @ Oregano i @ badp .W Pythonie 3 przekaż wynik,
list()
aby uzyskać tę samą listę 2D co metoda 2.metoda 2 - rozumienie listy,
zip_longest()
Alternatywa @ inspectorG4dget .
metoda 3 -
map()
ofmap()
- broken w Pythonie 3.6Ta niezwykle kompaktowa druga alternatywa @ SigigF działa z poszarpanymi listami 2D, w przeciwieństwie do jego pierwszego kodu, który używa numpy do transponowania i przechodzenia przez poszarpane listy. Ale Brak musi być wartością wypełnienia. (Nie, Brak przekazany do wewnętrznej mapy () nie jest wartością wypełnienia. Oznacza to, że nie ma funkcji przetwarzającej każdą kolumnę. Kolumny są właśnie przekazywane do zewnętrznej mapy (), która konwertuje je z krotek na listy.
Gdzieś w Pythonie 3
map()
przestałem znosić to nadużycie: pierwszym parametrem nie może być None, a nierówne iteratory są po prostu skracane do najkrótszych. Inne metody nadal działają, ponieważ dotyczy to tylko wewnętrznej mapy ().Metoda 4 -
map()
zmap()
revisitedNiestety poszarpane rzędy NIE stają się poszarpanymi kolumnami w Pythonie 3, są one po prostu obcięte. Postęp boo hoo.
źródło
Trzy opcje do wyboru:
1. Mapa z Zip
2. Zrozumienie listy
3. Do dołączania w pętli
I aby zobaczyć wyniki:
źródło
Może nie jest to najbardziej eleganckie rozwiązanie, ale oto rozwiązanie wykorzystujące zagnieżdżone pętle while:
źródło
źródło
more_itertools.unzip()
jest łatwy do odczytania i działa również z generatorami.lub równoważnie
źródło
Oto rozwiązanie dla transpozycji listy list, która niekoniecznie jest kwadratowa:
źródło
źródło