回答:
いかがですか
map(list, zip(*l))
--> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Python 3.xの場合、ユーザーは次を使用できます
list(map(list, zip(*l)))
説明:
何が起こっているのかを理解するために知っておくべきことが2つあります。
zip(*iterables)
これzip
は、それぞれが反復可能でなければならない任意の数の引数を期待することを意味します。例えばzip([1, 2], [3, 4], [5, 6])
。args
にf(*args)
が呼び出さf
れargs
ますf
。質問からの入力に戻ることはl = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
、zip(*l)
と同等zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
です。残りは、結果がタプルのリストではなくリストのリストであることを確認するだけです。
list(zip(*l))
のPython 3で正常に動作する
zip(*l)
Python 2と同様に)機能しますが、リストのリストではなく、タプルのリストを取得します。もちろん、list(list(it))
は常にと同じですlist(it)
。
これを行う1つの方法は、NumPyトランスポーズを使用することです。リストの場合:
>>> import numpy as np
>>> np.array(a).T.tolist()
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
または、zipなしの別のもの:
>>> map(list,map(None,*a))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
map
できるとは思いもしませんでした。ここでは、しかし、2つのコールを必要としないわずかな改良があります:map(lambda *a: list(a), *l)
map(None, ...)
Py3では動作しないようです。ジェネレータは作成されますがnext()
、すぐにエラーが発生しますTypeError: 'NoneType' object is not callable
。
イエナのソリューションと同等:
>>> 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()
、この解決策はPython精神の中で最も高いものです...
面白さのために、有効な長方形とm [0]が存在すると仮定
>>> 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]))]
。もちろん、リストl
が空でないことを確認する必要があります。
メソッド1と2はPython 2または3で機能し、不規則な長方形の 2Dリストで機能します。つまり、内部リストは互いに(不揃い)または外部リスト(長方形)と同じ長さである必要はありません。他の方法も、複雑です。
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()
なる
itertools.izip_longest()
Python 2itertools.zip_longest()
Python 3デフォルトのfillvalueはNone
です。@イエナさんのおかげで答え、map()
リストに内側のタプルを変更しています。ここでは、イテレータをリストに変えています。@Oreganoと@badpのコメントに感謝します。
Python 3では、list()
メソッド2と同じ2Dリストを取得するために結果を渡します。
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, '-']]
map()
of map()
— 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]]
この非常にコンパクトな@SiggyFの2番目の代替方法は、numpyを使用して不規則なリストを転置および通過させる最初のコードとは異なり、不規則な2Dリストで機能します。しかし、どれも塗りつぶしの値である必要はありません。(いいえ、内部のmap()に渡されるNoneは塗りつぶしの値ではありません。これは、各列を処理する関数がないことを意味します。列は外部のmap()に渡されるだけで、タプルからリストに変換されます。
Python 3のどこかで、map()
このすべての悪用を我慢しなくなりました。最初のパラメーターをNoneにすることはできず、不規則なイテレーターは最短に切り捨てられるだけです。これは内部のmap()にのみ適用されるため、他のメソッドは引き続き機能します。
map()
のmap()
再考>>> 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+
残念ながら、不揃いな行はPython 3では不揃いな列にはなりません。それらは単に切り捨てられます。ブーフー進歩。
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]
おそらく最もエレガントな解決策ではないかもしれませんが、ネストされたwhileループを使用した解決策を次に示します。
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()
読みやすく、ジェネレーターでも動作します。
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
または同等に
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
#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
サイズが均一でない場合(たとえば、一部の行が他の行よりも短い場合)zip
はそれを補正せず、代わりに出力から行を削除します。だからl=[[1,2],[3,4],[5]]
あなたに与える[[1,3,5]]
。