Bagaimana cara menggabungkan daftar ke dalam daftar tupel?

298

Apa pendekatan Pythonic untuk mencapai yang berikut ini?

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

Setiap anggota list_cadalah tuple, yang anggota pertamanya berasal list_adan yang kedua berasal list_b.

rubayeet
sumber

Jawaban:

443

Dengan Python 2:

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

Dengan Python 3:

>>> 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)]
KAMU
sumber
77
Anda harus tahu bahwa fungsi zip berhenti di akhir daftar terpendek, yang mungkin tidak selalu seperti yang Anda inginkan. yang itertoolsmodul mendefinisikan zip_longest()metode yang berhenti di akhir daftar terpanjang, mengisi nilai-nilai yang hilang dengan sesuatu yang Anda berikan sebagai parameter.
Adrien Plisson
5
@Adrien: sorakan untuk komentar Anda yang berlaku. Untuk Python 2.x s/zip_longest()/izip_longest(),. Berganti nama dengan Python 3.x ke zip_longest().
mechanical_meat
dapatkah saya membuat [(1,5), (1,6), (1,7), (1,8), (2,5), (2,6), seterusnya] menggunakan perintah zip?
Mona Jalal
3
@OnaJalal: tidak, itu tidak berpasangan, itu menciptakan produk dari daftar. itertools.product()apakah itu.
Martijn Pieters
2
perhatikan, setidaknya dalam zip python3.6 tidak mengembalikan daftar. Jadi Anda perlu daftar (zip (list_a, list_b)) sebagai gantinya
Supamee
141

Dalam python 3.0 zip mengembalikan objek zip. Anda bisa mendapatkan daftar dengan menelepon list(zip(a, b)).

Lodewijk
sumber
3
Ini mungkin sepele, tetapi ingatlah bahwa menggunakan ini secara langsung dalam for for memberi Anda generator yang akan habis setelah menggunakannya sekali. Simpan menjadi variabel jika Anda ingin menggunakannya lebih sering
Hakaishin
13

Anda dapat menggunakan peta lambda

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

Ini juga akan berfungsi jika ada panjang daftar asli tidak cocok

Kesatria Kegelapan
sumber
1
Mengapa menggunakan lambda? map(None, a,b)
Padraic Cunningham
Saya hanya memiliki akses ke python 3.5.
Dark Knight
3
Jika Anda menggunakan python3 maka c tidak akan menjadi daftar itu akan menjadi objek peta, juga menggunakan lambda akan jauh lebih efisien daripada hanya zip, jika Anda memiliki daftar panjang yang berbeda dan ingin mengatasinya maka Anda akan menggunakan izip_longest / zip_longest
Padraic Cunningham
8

Anda sedang mencari zip fungsi bawaan .

Mizipzor
sumber
6

Saya tidak yakin apakah ini cara pythonic atau tidak tetapi ini tampak sederhana jika kedua daftar memiliki jumlah elemen yang sama:

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))]
Vipin
sumber
5

Saya tahu ini adalah pertanyaan lama dan sudah dijawab, tetapi untuk beberapa alasan, saya masih ingin memposting solusi alternatif ini. Saya tahu mudah untuk mengetahui fungsi bawaan yang melakukan "keajaiban" yang Anda butuhkan, tetapi tidak ada salahnya Anda tahu Anda bisa melakukannya sendiri.

>>> 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')]
Kruger
sumber
2
Mengubah salah satu daftar input (jika panjangnya berbeda) bukanlah efek samping yang bagus. Juga, dua tugas carddi dalam if-eliftidak diperlukan, itu sebabnya Anda memiliki continue. (Bahkan, tanpa continueAnda tidak perlu mengubah daftar: kedua tugas yang disebutkan sebelumnya kemudian harus disimpan dan menjadi masing card = (list_1[i], '')- card = ('', list_2[1])masing.)
ᴠɪɴᴄᴇɴᴛ
5

Output yang Anda tunjukkan dalam pernyataan masalah bukanlah tupel tetapi daftar

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

cek untuk

type(list_c)

mempertimbangkan Anda ingin hasilnya sebagai tuple dari list_a dan list_b, lakukan

tuple(zip(list_a,list_b)) 
cyborg
sumber
Dari sudut pandang saya, sepertinya itulah yang saya cari dan berfungsi dengan baik untuk keduanya (daftar dan tuple). Karena ketika Anda menggunakan cetak , Anda akan melihat nilai yang tepat (seperti yang diharapkan dan disebutkan oleh @cyborg dan @Lodewijk) dan tidak ada yang terkait dengan objek seperti: <map object at 0x000001F266DCE5C0>atau <zip object at 0x000002629D204C88>. Setidaknya, solusi tentang peta dan zip (sendirian) tampaknya tidak lengkap (atau terlalu rumit) bagi saya.
Wagner_SOFC
1
Pertanyaannya menyatakan mereka menginginkan daftar tupel bukan tupel tupel.
goryh
1

Satu alternatif tanpa menggunakan zip:

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

Dalam hal seseorang ingin mendapatkan tidak hanya tupel 1 dengan 1, 2 dengan 2 ... tetapi semua kemungkinan kombinasi dari 2 daftar, yang akan dilakukan dengan

list_d = [(p1, p2) for p1 in list_a for p2 in list_b]
J0ANMM
sumber