Kết hợp hai danh sách và xóa các bản sao mà không xóa các bản sao trong danh sách gốc


115

Tôi có hai danh sách mà tôi cần kết hợp trong đó danh sách thứ hai có bất kỳ bản sao nào của danh sách đầu tiên bị bỏ qua. .. Hơi khó giải thích, vì vậy hãy để tôi đưa ra một ví dụ về mã trông như thế nào và kết quả là tôi muốn gì.

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]

Bạn sẽ nhận thấy rằng kết quả có danh sách đầu tiên, bao gồm hai giá trị "2" của nó, nhưng thực tế là danh sách thứ hai cũng có thêm giá trị 2 và 5 không được thêm vào danh sách đầu tiên.

Thông thường đối với những thứ như thế này, tôi sẽ sử dụng các bộ, nhưng một bộ trên first_list sẽ xóa các giá trị trùng lặp mà nó đã có. Vì vậy, tôi chỉ đơn giản là tự hỏi cách tốt nhất / nhanh nhất để đạt được sự kết hợp mong muốn này.

Cảm ơn.


3
Điều gì sẽ xảy ra nếu có ba số 2 trong second_list?
balpha

@balpha: Đúng vậy, tôi vẫn chưa quyết định hoàn toàn cách tôi muốn xử lý điều đó. Nó là một cái gì đó tôi đã nghĩ về, nhưng bỏ qua cho sự do dự của tôi về vấn đề này :)
Lee Olayvar

Câu trả lời:


168

Bạn cần thêm vào danh sách đầu tiên những phần tử của danh sách thứ hai không có trong danh sách đầu tiên - tập hợp là cách dễ nhất để xác định chúng là phần tử nào, như sau:

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]

Hoặc nếu bạn thích một lớp lót 8-)

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

2
Hoặc nếu bạn cần nó sắp xếp: in first_list + sắp xếp (set (second_list) - bộ (first_list))
hughdbrown

2
Danh sách (set (first_list) | set (second_list)) # | được đặt giao lộ xem stackoverflow.com/questions/4674013/…
staticd

1
@staticd: Có, nhưng câu trả lời sai. Chỉ có một 2trong kết quả của bạn, khi phải có hai trong số chúng.
RichieHindle 30/09/13

Giáo sư. Bạn đúng. Hoàn toàn bỏ lỡ rằng danh sách đầu tiên được phép trùng lặp. : P
staticd

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

7
Cuối cùng là một câu trả lời không liên quan đến việc đúc thành bộ! Thanh danh.
SuperFamousGuy

4
này là trong thực tế O (n * m) nhưng có thể có ích khi bạn có danh sách những thứ phi hashable và hiệu suất không phải là một mối quan tâm
alcuadrado

1
Những gì tôi không muốn bất kỳ trùng lặp nào, không từ thứ nhất hay thứ hai?
Dejell

Kỹ thuật này bảo toàn thứ tự của các thuộc tính trong danh sách, điều này không đúng với trường hợp này set. 👍
Subhash Bhushan

29

Bạn có thể sử dụng các bộ:

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]

Vâng Cảm ơn tôi đã hiểu. Điều này sẽ hoạt động tốt. resultList = first_list + list (set (second_list) -set (first_list))
Kathiravan Umaidurai

9

Bạn có thể đưa điều này xuống một dòng mã duy nhất nếu bạn sử dụng 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]

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

print( set( first_list + second_list ) )

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

1
first_list setify và bạn "set"
u0b34a0f6ae

Danh sách kết quả sẽ không được sắp xếp.
avakar

1
Điều gì sẽ xảy ra nếu tôi cũng không muốn bất kỳ danh sách nào có các bản sao? Bằng cách này nếu một danh sách có bản sao họ sẽ trở lại
Dejell

5

Đơn giản nhất với tôi là:

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
Đó là một giải pháp tuyệt vời, nhưng hãy nhớ rằng nó sẽ không làm việc nếu chúng ta cố gắng làm cho hàng loạt các từ điển một tập ví dụ (sẽ nâng cao TypeError: unhashable type: 'dict')
lakesare

2

Bạn cũng có thể kết hợp các phản hồi của RichieHindle và Ned Batchelder cho thuật toán O (m + n) trường hợp trung bình duy trì thứ tự:

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

Lưu ý rằng x in scó độ phức tạp trường hợp xấu nhất là O (m) , vì vậy độ phức tạp trong trường hợp xấu nhất của mã này vẫn là O (m * n) .


0

Điều này có thể giúp

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

Hàm union hợp nhất danh sách thứ hai với danh sách đầu tiên, không sao chép một phần tử của a, nếu nó đã ở trong a. Tương tự với toán tử set union. Chức năng này không thay đổi b. Nếu a = [1,2,3] b = [2,3,4]. Sau khi union (a, b) tạo ra a = [1,2,3,4] và b = [2,3,4]



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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.