Listeleri bir grup listesine nasıl birleştirebilirim?


298

Aşağıdakilere ulaşmak için Pythonic yaklaşımı nedir?

# Original lists:

list_a = [1, 2, 3, 4]
list_b = [5, 6, 7, 8]

# List of tuples from 'list_a' and 'list_b':

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

Her üyesi list_c, ilk üyesi olan list_ave ikinci üyesi olan bir demettir list_b.

Yanıtlar:


443

Python 2'de:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> zip(list_a, list_b)
[(1, 5), (2, 6), (3, 7), (4, 8)]

Python 3'te:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> list(zip(list_a, list_b))
[(1, 5), (2, 6), (3, 7), (4, 8)]

77
zip işlevinin en kısa listenin sonunda durduğunu bilmek zorundasınız, bu her zaman istediğiniz şey olmayabilir. itertoolsmodül tanımlar zip_longest()parametre olarak temin şeyle eksik değerleri doldurarak, en uzun listenin sonunda durur yöntemi.
Adrien Plisson

5
@ Adrien: uygulanabilir yorumunuz için alkış. Python 2.x için s/zip_longest()/izip_longest(),. Python 3.x olarak yeniden adlandırıldı zip_longest().
mechanical_meat

zip komutunu kullanarak [(1,5), (1,6), (1,7), (1,8), (2,5), (2,6) vb.] oluşturabilir miyim?
Mona Jalal

3
@MonaJalal: hayır, bu eşleşmiyor, bu listelerin ürününü yaratıyor . itertools.product()bunu yapar.
Martijn Pieters

2
not, en azından python3.6 zip içinde bir liste döndürmez. Bunun yerine listeye ihtiyacınız var (zip (list_a, list_b))
Supamee

142

Python 3.0 zip içinde bir zip nesnesi döndürür. Arayarak bir liste alabilirsiniz list(zip(a, b)).


3
Bu önemsiz olabilir, ancak bunu doğrudan bir for döngüsünde kullanmanın, bir kez kullandıktan sonra tükenecek bir jeneratör verdiği konusunda uyarılmalıdır. Daha sık kullanmak istiyorsanız bir değişkene kaydedin
Hakaishin

13

Harita lambda'yı kullanabilirsiniz

a = [2,3,4]
b = [5,6,7]
c = map(lambda x,y:(x,y),a,b)

Bu, orijinal listelerin uzunluğu eşleşmediğinde de çalışır


1
Neden lambda kullanıyorsunuz? map(None, a,b)
Padraic Cunningham

Yalnızca python 3.5'e erişimim var.
Dark Knight

3
Eğer python3 kullanıyorsanız o zaman c bir liste nesnesi olurdu, bir harita nesnesi olurdu, ayrıca bir lambda kullanmak sadece zipping'den çok daha az verimli olacak, farklı uzunluk listeleriniz varsa ve bunu kullanmak istiyorsanız izip_longest / zip_longest
Padraic Cunningham


6

Bu bir pitonik yolu olup olmadığını emin değilim ama her iki liste aynı sayıda öğe varsa bu basit görünüyor:

list_a = [1, 2, 3, 4]

list_b = [5, 6, 7, 8]

list_c=[(list_a[i],list_b[i]) for i in range(0,len(list_a))]

5

Bunun eski bir soru olduğunu ve zaten cevaplandığını biliyorum, ama bazı nedenlerden dolayı hala bu alternatif çözümü göndermek istiyorum. Hangi yerleşik fonksiyonun ihtiyacınız olan "büyüyü" yaptığını bulmak kolay, ama bunu kendiniz yapabileceğinizi bilmek acı vermez.

>>> list_1 = ['Ace', 'King']
>>> list_2 = ['Spades', 'Clubs', 'Diamonds']
>>> deck = []
>>> for i in range(max((len(list_1),len(list_2)))):
        while True:
            try:
                card = (list_1[i],list_2[i])
            except IndexError:
                if len(list_1)>len(list_2):
                    list_2.append('')
                    card = (list_1[i],list_2[i])
                elif len(list_1)<len(list_2):
                    list_1.append('')
                    card = (list_1[i], list_2[i])
                continue
            deck.append(card)
            break
>>>
>>> #and the result should be:
>>> print deck
>>> [('Ace', 'Spades'), ('King', 'Clubs'), ('', 'Diamonds')]

2
Giriş listelerinden birini değiştirmek (uzunlukları farklıysa) hoş bir yan etki değildir. Ayrıca, iki atamalar cardiçinde if-elifsen neden olduğunu, gerekli değildir continue. (Aslında, continuesiz olmadan listeleri değiştirmek zorunda kalmazsınız: daha önce bahsedilen her iki ödev de daha sonra tutulmalı card = (list_1[i], '')ve card = ('', list_2[1])sırasıyla olmalıdır.)
ᴠɪɴᴄᴇɴᴛ

5

Sorun ifadesinde gösterdiğiniz çıktı grup değil liste

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

kontrol

type(list_c)

Sonucun list_a ve list_b dışında bir grup olmasını istediğinizi göz önünde bulundurarak,

tuple(zip(list_a,list_b)) 

Benim açımdan, aradığım şey ve her ikisi için de (liste ve demet) iyi çalışmak gibi görünüyor. Çünkü print'i kullandığınızda doğru değeri (@cyborg ve @Lodewijk tarafından beklendiği ve belirtildiği gibi) ve nesne ile ilgili hiçbir şey görmeyeceksiniz : <map object at 0x000001F266DCE5C0>veya <zip object at 0x000002629D204C88>. En azından, harita ve zip (tek başına) ile ilgili çözüm benim için eksik (veya çok karmaşık) görünüyor.
Wagner_SOFC

1
Soru, bir grup tuples değil, bir tuples listesi istediklerini belirtiyor.
goryh

1

Kullanmadan bir alternatif zip:

list_c = [(p1, p2) for idx1, p1 in enumerate(list_a) for idx2, p2 in enumerate(list_b) if idx1==idx2]

Biri sadece 1. ile 2., 2. ile 2. tuplleri almak istemiyorsa ... ancak 2 listenin tüm olası kombinasyonları,

list_d = [(p1, p2) for p1 in list_a for p2 in list_b]
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.