Menggabungkan dua daftar dan menghapus duplikat, tanpa menghapus duplikat dalam daftar asli

115

Saya memiliki dua daftar yang perlu saya gabungkan di mana daftar kedua memiliki duplikat dari daftar pertama yang diabaikan. .. Agak sulit untuk menjelaskan, jadi izinkan saya menunjukkan contoh seperti apa kode itu, dan apa yang saya inginkan sebagai hasilnya.

first_list = [1, 2, 2, 5]

second_list = [2, 5, 7, 9]

# The result of combining the two lists should result in this list:
resulting_list = [1, 2, 2, 5, 7, 9]

Anda akan melihat bahwa hasil memiliki daftar pertama, termasuk dua nilai "2", tetapi fakta bahwa second_list juga memiliki nilai 2 dan 5 tambahan tidak ditambahkan ke daftar pertama.

Biasanya untuk sesuatu seperti ini saya akan menggunakan set, tetapi satu set pada first_list akan membersihkan nilai duplikat yang sudah dimilikinya. Jadi saya hanya ingin tahu cara terbaik / tercepat untuk mencapai kombinasi yang diinginkan ini.

Terima kasih.

Lee Olayvar
sumber
3
Bagaimana jika ada tiga angka 2 second_list?
balpha
@balpha: Ya, saya belum sepenuhnya memutuskan bagaimana saya ingin menanganinya. Ini adalah sesuatu yang saya pikirkan, tetapi ditinggalkan karena keraguan saya tentang masalah ini :)
Lee Olayvar

Jawaban:

168

Anda perlu menambahkan ke daftar pertama elemen-elemen dari daftar kedua yang tidak ada di daftar pertama - set adalah cara termudah untuk menentukan elemennya, seperti ini:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

in_first = set(first_list)
in_second = set(second_list)

in_second_but_not_in_first = in_second - in_first

result = first_list + list(in_second_but_not_in_first)
print(result)  # Prints [1, 2, 2, 5, 9, 7]

Atau jika Anda lebih suka satu baris 8-)

print(first_list + list(set(second_list) - set(first_list)))
RichieHindle
sumber
2
Atau ini jika Anda membutuhkannya diurutkan: print first_list + sort (set (second_list) - set (first_list))
hughdbrown
2
Daftar (set (daftar_pertama) | set (daftar_kedua)) # | sudah diatur persimpangan lihat stackoverflow.com/questions/4674013/…
staticd
1
@staticd: Ya, tapi itu memberikan jawaban yang salah. Hanya ada satu 2hasil Anda, padahal seharusnya ada dua.
RichieHindle
Ups. Kamu benar. Benar-benar merindukan bahwa daftar pertama itu diperbolehkan duplikat. : P
staticd
66
resulting_list = list(first_list)
resulting_list.extend(x for x in second_list if x not in resulting_list)
Ned Batchelder
sumber
7
Akhirnya jawaban yang tidak melibatkan casting ke dalam set! Pujian.
SuperFamousGuy
4
ini sebenarnya adalah O (n * m) tetapi mungkin berguna ketika Anda memiliki daftar hal-hal yang tidak dapat di-hash dan kinerja tidak menjadi perhatian
alcuadrado
1
Apa yang saya tidak ingin ada duplikat baik dari pertama maupun dari kedua?
Dejell
Teknik ini mempertahankan urutan atribut dalam daftar, yang tidak terjadi pada kasus set. 👍
Subhash Bhushan
29

Anda dapat menggunakan set:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

resultList= list(set(first_list) | set(second_list))

print(resultList)
# Results in : resultList = [1,2,5,7,9]
Kathiravan Umaidurai
sumber
Ya Terima kasih saya mengerti. Ini akan bekerja dengan baik. resultList = first_list + list (set (second_list) -set (first_list))
Kathiravan Umaidurai
9

Anda dapat menurunkannya menjadi satu baris kode jika Anda menggunakan numpy:

a = [1,2,3,4,5,6,7]
b = [2,4,7,8,9,10,11,12]

sorted(np.unique(a+b))

>>> [1,2,3,4,5,6,7,8,9,10,11,12]
mosegui
sumber
7
first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

print( set( first_list + second_list ) )
Paul Roub
sumber
5
resulting_list = first_list + [i for i in second_list if i not in first_list]
Daniel Roseman
sumber
1
setify first_list dan Anda "set"
u0b34a0f6ae
Daftar yang dihasilkan tidak akan diurutkan.
avakar
1
Bagaimana jika saya juga tidak ingin ada daftar yang memiliki duplikat sama sekali? dengan cara ini jika satu daftar memiliki duplikat, mereka akan kembali
Dejell
5

Yang paling sederhana bagi saya adalah:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

merged_list = list(set(first_list+second_list))
print(merged_list)

#prints [1, 2, 5, 7, 9]
Rafiq
sumber
1
Itu solusi yang bagus, tetapi perlu diingat bahwa itu tidak akan berhasil jika kita mencoba membuat susunan kamus menjadi satu set, misalnya (akan mengangkat TypeError: unhashable type: 'dict')
lakesare
2

Anda juga dapat menggabungkan respons RichieHindle dan Ned Batchelder untuk algoritme rata-rata kasus O (m + n) yang mempertahankan keteraturan:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

fs = set(first_list)
resulting_list = first_list + [x for x in second_list if x not in fs]

assert(resulting_list == [1, 2, 2, 5, 7, 9])

Perhatikan bahwa x in skasus terburuk memiliki kompleksitas O (m) , jadi kompleksitas kasus terburuk kode ini tetap O (m * n) .

z0r
sumber
0

Ini mungkin bisa membantu

def union(a,b):
    for e in b:
        if e not in a:
            a.append(e)

Fungsi gabungan menggabungkan daftar kedua menjadi pertama, tanpa menduplikasi elemen a, jika sudah ada di a. Mirip dengan set union operator. Fungsi ini tidak berubah b. Jika a = [1,2,3] b = [2,3,4]. Setelah penyatuan (a, b) membuat a = [1,2,3,4] dan b = [2,3,4]

VeilEclipse
sumber
0

Berdasarkan resepnya :

result_list = list (set (). union (first_list, second_list))

Alon
sumber
-2
    first_list = [1, 2, 2, 5]
    second_list = [2, 5, 7, 9]

    newList=[]
    for i in first_list:
        newList.append(i)
    for z in second_list:
        if z not in newList:
            newList.append(z)
    newList.sort()
    print newList

[1, 2, 2, 5, 7, 9]

pengguna4846254
sumber