Listeleri aktar


241

Hadi alalım:

l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Aradığım sonuç

r = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

ve yok

r = [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

Çok takdir

Yanıtlar:


336

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:

  1. Zip imzası : zip(*iterables)Bu, zipher biri yinelenebilir olması gereken rasgele sayıda argüman beklemek anlamına gelir . Örn zip([1, 2], [3, 4], [5, 6]).
  2. Ambalajdan çıkartılmış bağımsız değişken listeleri : bağımsız değişkenlerin bir dizisi ele alındığında args, f(*args)arayacak fher öğe bu şekilde argsayrı 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.


67
Dikkat: eğer leşit (diyelim ki, bazı satırlar diğerlerinden daha kısadır) boyutlandırılmadı, zipolacak değil bunun için telafi ve bunun yerine çıkışından satırları uzakta doğrayın. Size l=[[1,2],[3,4],[5]]verir [[1,3,5]].
badp

29
itertoolsFonksiyon zip_longest()dengesiz listeleri ile çalışır. Bkz. DOCS
Kekik

13

7
Bence list(zip(*l))Python 3'te bile düzgün çalışıyor.
Stefano

3
@Stefano Çalışır ( 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).
Alex Shpilkin

62

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]]

8
İkincisini seviyorum - mapbunu yapabileceğini fark etmedim . İşte 2 çağrı gerektirmeyen hafif bir ayrıntılandırma:map(lambda *a: list(a), *l)
Lee D

7
Düzensiz listelere dikkat ettiği için bu daha iyi bir cevap olmamalı mı?
Leon

15
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.
Mad Physicist

57

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]]

12
Liste kavrayışı şimdi tercih edildiğinden map(), bu çözüm Python ruhunda en çok olan çözümdür ...
perror

26

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]]

aradığım ve başımı bulamadığım şey buydu. Hala @
jena'nın

3
Evet, bunu düzeltmek için birkaç lastik gerekiyor. Pekala, birçok deneme.
matchew

9
Hala doğru değil - bu sadece boyutlar kare olduğunda işe yarar! Öyle olmalı: [[j[i] for j in l] for i in range(len(l[0]))]. Tabii ki, listenin lboş olmadığından emin olmalısınız .
Lee D

@LeeD hala jena örneğinde benim için çalışmıyor l = [[1,2], [3,4], [5]]
ocaklar

3
@hobs Bu, badp'nin örneğiydi, jena'ya yanıt veriyordu. Ancak, bunun benim için anlamlı olduğundan emin değilim. IMO, transpozisyon dikdörtgen bir matris anlamına gelir - bir liste listesi olarak temsil edildiğinde, tüm dahili listelerin aynı uzunlukta olması gerektiği anlamına gelir. Bu örneğin "aktarılması" olarak ne sonuç istersiniz?
Lee D

22

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.

kurulum

import itertools
import six

list_list = [[1,2,3], [4,5,6, 6.1, 6.2, 6.3], [7,8,9]]

yöntem 1 - 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

Varsayı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.


yöntem 2 - liste anlama, 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 .


yöntem 3 - 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.


yöntem, 4 - 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.


7

Seçebileceğiniz üç seçenek:

1. Zip ile Harita

solution1 = map(list, zip(*l))

2. Liste Anlama

solution2 = [list(i) for i in zip(*l)]

3. Döngü Ekleme İçin

solution3 = []
for i in zip(*l):
    solution3.append((list(i)))

Ve sonuçları görüntülemek için:

print(*solution1)
print(*solution2)
print(*solution3)

# [1, 4, 7], [2, 5, 8], [3, 6, 9]

0

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


0

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

-1

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])

-2
    #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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.