Yanıtlar:
Peki ya
map(list, zip(*l))
--> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Python 3.x kullanıcıları için
list(map(list, zip(*l)))
Açıklama:
Neler olduğunu anlamak için bilmemiz gereken iki şey var:
zip(*iterables)
Bu, zip
her biri yinelenebilir olması gereken rasgele sayıda argüman beklemek anlamına gelir . Örn zip([1, 2], [3, 4], [5, 6])
.args
, f(*args)
arayacak f
her öğe bu şekilde args
ayrı bir konumsal bir argümandır f
.Sorunun girdisine geri dönersek l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
, zip(*l)
eşdeğer olur zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
. Gerisi sadece sonucun bir grup listesi yerine bir liste listesi olduğundan emin olmaktır.
list(zip(*l))
Python 3'te bile düzgün çalışıyor.
zip(*l)
Python 2'de olduğu gibi), ancak listelerin bir listesini değil, tuples listesini alırsınız. Tabii ki, list(list(it))
her zaman aynı şeydir list(it)
.
Bunu yapmanın bir yolu NumPy devrik ile yapmaktır. Liste için a:
>>> import numpy as np
>>> np.array(a).T.tolist()
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Veya fermuarsız başka bir tane:
>>> map(list,map(None,*a))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
map
bunu yapabileceğini fark etmedim . İşte 2 çağrı gerektirmeyen hafif bir ayrıntılandırma:map(lambda *a: list(a), *l)
map(None, ...)
Py3 için çalışmıyor gibi görünüyor. Jeneratör oluşturulur ancak next()
hemen bir hata tutarsa: TypeError: 'NoneType' object is not callable
.
Jena'nın çözümüne eşit olarak:
>>> 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()
, bu çözüm Python ruhunda en çok olan çözümdür ...
sadece eğlence için, geçerli dikdörtgenler ve m [0] olduğunu varsayarak
>>> 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]))]
. Tabii ki, listenin l
boş olmadığından emin olmalısınız .
Yöntem 1 ve 2, Python 2 veya 3'te çalışır ve düzensiz, dikdörtgen 2B listelerde çalışır. Bu, iç listelerin birbiriyle (düzensiz) veya dış listelerle (dikdörtgen) aynı uzunluklara sahip olması gerekmediği anlamına gelir. Diğer yöntemler, karmaşık.
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()
olur
itertools.izip_longest()
Python 2'deitertools.zip_longest()
Python 3'teVarsayılan dolgu değeri None
. @ Jena'nın cevabı sayesinde , map()
iç tupleleri listelere değiştiriyor. Burada yineleyicileri listelere dönüştürüyor. @ Oregano ve @ badp'nin yorumları sayesinde .
Python 3'te, list()
yöntem 2 ile aynı 2D listesini almak için sonucu iletin.
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, '-']]
@ İnspectorG4dget alternatif .
map()
arasında map()
- Python 3.6 kırık>>> 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]]
Bu olağanüstü kompakt @SiggyF ikinci alternatif , düzensiz listelerin aktarılması ve içinden geçirilmesi için numpy kullanan ilk kodunun aksine düzensiz 2D listelerle çalışır. Ancak hiçbiri dolgu değeri olmamalıdır. (Hayır, iç haritaya () iletilen Yok değeri dolgu değeri değildir. Bu, her sütunu işlemek için bir işlev olmadığı anlamına gelir.
Python 3'te bir yerde, map()
tüm bu kötüye kullanımlara katlanmaktan vazgeçti: ilk parametre Yok olamaz ve düzensiz yineleyiciler en kısa süreye kısaltılır. Diğer yöntemler hala çalışır çünkü bu sadece iç harita () için geçerlidir.
map()
arasında map()
revisited>>> 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+
Ne yazık ki düzensiz satırlar Python 3'te düzensiz sütunlar haline gelmez, sadece kesilirler. Boo hoo ilerleme.
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]
Belki en zarif çözüm değil, ama iç içe döngüleri kullanarak bir çözüm:
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()
okunması kolaydır ve jeneratörlerle de çalışır.
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
Veya eşdeğer olarak
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
Mutlaka kare olmayan listelerin bir listesini aktarmak için bir çözüm:
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
eşit (diyelim ki, bazı satırlar diğerlerinden daha kısadır) boyutlandırılmadı,zip
olacak değil bunun için telafi ve bunun yerine çıkışından satırları uzakta doğrayın. Sizel=[[1,2],[3,4],[5]]
verir[[1,3,5]]
.