การรวมสองรายการและลบรายการที่ซ้ำกันโดยไม่ต้องลบรายการที่ซ้ำกันในรายการเดิม


118

ฉันมีสองรายการที่ฉันต้องรวมโดยที่รายการที่สองมีรายการที่ซ้ำกันของรายการแรกที่ละเว้น .. อธิบายยากไปหน่อยขอผมแสดงตัวอย่างว่าโค้ดมีลักษณะอย่างไรและผลลัพธ์ที่ผมต้องการคืออะไร

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]

คุณจะสังเกตเห็นว่าผลลัพธ์มีรายการแรกรวมถึงค่า "2" สองค่า แต่ความจริงที่ second_list ยังมีค่า 2 และ 5 เพิ่มเติมจะไม่ถูกเพิ่มลงในรายการแรก

โดยปกติสำหรับสิ่งนี้ฉันจะใช้ชุด แต่ชุดใน first_list จะล้างค่าที่ซ้ำกันที่มีอยู่แล้ว ดังนั้นฉันแค่สงสัยว่าวิธีใดดีที่สุด / เร็วที่สุดในการบรรลุชุดค่าผสมที่ต้องการนี้

ขอบคุณ.


3
จะเกิดอะไรขึ้นถ้ามี 3 2 ในsecond_list?
balpha

@ บาลฟา: เออฉันยังไม่ได้ตัดสินใจอย่างเต็มที่ว่าจะจัดการยังไง มันเป็นสิ่งที่ฉันเคยคิด แต่ทิ้งไว้เพราะความไม่แน่ใจในเรื่องนี้ :)
Lee Olayvar

คำตอบ:


170

คุณต้องผนวกเข้ากับรายการแรกองค์ประกอบของรายการที่สองที่ไม่ได้อยู่ในรายการแรกชุดเป็นวิธีที่ง่ายที่สุดในการพิจารณาว่าองค์ประกอบใดเป็นดังนี้:

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]

หรือถ้าคุณชอบ one-liners 8-)

print(first_list + list(set(second_list) - set(first_list)))

2
หรือสิ่งนี้ถ้าคุณต้องการเรียงลำดับ: print first_list + sorted (set (second_list) - set (first_list))
hughdbrown

2
รายการ (set (first_list) | set (second_list)) # | กำหนดจุดตัดดูstackoverflow.com/questions/4674013/…
staticd

1
@staticd: ใช่ แต่นั่นให้คำตอบที่ผิด 2ผลลัพธ์ของคุณมีเพียงหนึ่งเดียวเมื่อควรมีสองอย่าง
RichieHindle

อ๊ะ. คุณถูก. พลาดโดยสิ้นเชิงที่รายการแรกได้รับอนุญาตให้ซ้ำกัน : P
สถิต

67
resulting_list = list(first_list)
resulting_list.extend(x for x in second_list if x not in resulting_list)

7
ในที่สุดก็ได้คำตอบที่ไม่เกี่ยวกับการแคสเป็นเซ็ต! ความรุ่งโรจน์
SuperFamousGuy

4
นี่เป็นความจริง O (n * m) แต่อาจมีประโยชน์เมื่อคุณมีรายการสิ่งที่ไม่สามารถ
ซักได้

1
สิ่งที่ฉันไม่ต้องการให้ซ้ำกันทั้งจากครั้งแรกและครั้งที่สอง?
Dejell

เทคนิคนี้รักษาลำดับของแอตทริบิวต์ในรายการซึ่งไม่เป็นเช่นsetนั้น 👍
Subhash Bhushan

32

คุณสามารถใช้ชุด:

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]

ใช่ขอบคุณฉันเข้าใจแล้ว วิธีนี้จะทำงานได้ดี resultList = first_list + list (set (second_list) -set (first_list))
Kathiravan Umaidurai

9

คุณสามารถนำสิ่งนี้ลงในโค้ดบรรทัดเดียวได้หากคุณใช้ 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]


5
resulting_list = first_list + [i for i in second_list if i not in first_list]

1
setify first_list และคุณ "set"
u0b34a0f6ae

รายการผลลัพธ์จะไม่ถูกจัดเรียง
avakar

1
จะเกิดอะไรขึ้นถ้าฉันไม่ต้องการให้รายการมีรายการที่ซ้ำกันเลย? ด้วยวิธีนี้หากรายการใดรายการหนึ่งซ้ำกันพวกเขาจะกลับมา
Dejell

5

ง่ายที่สุดสำหรับฉันคือ:

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]

1
นั่นเป็นทางออกที่ดี แต่โปรดจำไว้ว่ามันจะไม่ได้ผลหากเราพยายามสร้างพจนานุกรมหลายชุดเช่น (จะเพิ่มTypeError: unhashable type: 'dict')
Lakesare

2

คุณยังสามารถรวมการตอบสนองของ RichieHindle และ Ned Batchelder สำหรับอัลกอริทึมO (m + n) กรณีเฉลี่ยที่รักษาลำดับ:

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

ทราบว่าx in sมีความซับซ้อนที่เลวร้ายที่สุดกรณีของO (เมตร)ดังนั้นกรณีที่แย่ที่สุดความซับซ้อนของรหัสนี้ยังคงเป็นO (m * n)


0

สิ่งนี้อาจช่วยได้

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

ฟังก์ชันยูเนี่ยนจะรวมรายการที่สองไว้ในรายการแรกโดยไม่ต้องทำซ้ำองค์ประกอบของ a หากมีอยู่แล้วในไฟล์. คล้ายกับ set union operator ฟังก์ชันนี้ไม่เปลี่ยนแปลง b. ถ้า a = [1,2,3] b = [2,3,4] หลังจากสหภาพ (a, b) สร้าง a = [1,2,3,4] และ b = [2,3,4]



โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.