Łączenie dwóch list i usuwanie duplikatów bez usuwania duplikatów z oryginalnej listy


115

Mam dwie listy, które muszę połączyć, gdzie druga lista ma zignorowane duplikaty pierwszej listy. .. Trochę trudne do wyjaśnienia, więc pozwól mi pokazać przykład tego, jak wygląda kod i czego oczekuję od wyniku.

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]

Zauważysz, że wynik ma pierwszą listę, w tym dwie wartości „2”, ale fakt, że second_list ma również dodatkową wartość 2 i 5, nie jest dodawany do pierwszej listy.

Normalnie do czegoś takiego użyłbym zestawów, ale zestaw na first_list wyczyściłby zduplikowane wartości, które już ma. Zastanawiam się więc po prostu, jaki najlepszy / najszybszy sposób na osiągnięcie tej pożądanej kombinacji.

Dzięki.


3
A jeśli są trzy dwójki second_list?
balpha

@balpha: Tak, nie zdecydowałem jeszcze do końca, jak chcę sobie z tym poradzić. To jest coś, o czym myślałem, ale
pominąłem

Odpowiedzi:


168

Musisz dołączyć do pierwszej listy te elementy drugiej listy, których nie ma na pierwszej - zbiory są najłatwiejszym sposobem określenia, które to elementy, na przykład:

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]

Lub jeśli wolisz jednoliniowe 8-)

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

2
Lub to, jeśli potrzebujesz, posortowane: drukuj first_list + sort (set (second_list) - set (first_list))
hughdbrown

2
List (set (first_list) | set (second_list)) # | jest ustawione przecięcie patrz stackoverflow.com/questions/4674013/…
staticd

1
@staticd: Tak, ale to daje złą odpowiedź. W 2Twoim wyniku jest tylko jeden , a powinny być dwa.
RichieHindle,

ups. Masz rację. Całkowicie przegapiłem, że pierwsza lista była dozwolona jako duplikaty. : P
staticd

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

7
Wreszcie odpowiedź, która nie wymaga rzucania w zestawy! Sława.
SuperFamousGuy

4
w rzeczywistości jest to O (n * m), ale może być przydatne, gdy masz listę rzeczy, których nie można
skasować,

1
Czego nie chcę, żeby były powielane ani z pierwszego, ani z drugiego?
Dejell,

Ta technika zachowuje kolejność atrybutów na liście, co nie ma miejsca w przypadku set. 👍
Subhash Bhushan

29

Możesz użyć zestawów:

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]

Tak, dzięki, rozumiem. To zadziała dobrze. resultList = first_list + list (set (second_list) -set (first_list))
Kathiravan Umaidurai

9

Możesz sprowadzić to do jednej linii kodu, jeśli używasz 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
setify first_list i jesteś "set"
u0b34a0f6ae

Wynikowa lista nie zostanie posortowana.
avakar

1
A jeśli ja też nie chcę, aby na żadnej liście w ogóle były duplikaty? w ten sposób, jeśli jedna lista zawiera duplikaty, wrócą one
Dejell

5

Najprostszy dla mnie jest:

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
To świetne rozwiązanie, ale pamiętaj, że nie zadziała, jeśli spróbujemy stworzyć zestaw słowników, np. (Podniesie TypeError: unhashable type: 'dict')
lakesare

2

Możesz także połączyć odpowiedzi RichieHindle i Neda Batcheldera, aby uzyskać algorytm O (m + n) o średniej wielkości liter, który zachowuje porządek:

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

Zauważ, że x in sma złożoność w najgorszym przypadku O (m) , więc złożoność w najgorszym przypadku tego kodu wciąż wynosi O (m * n) .


0

To może pomóc

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

Funkcja sumująca scala drugą listę w pierwszą, bez duplikowania elementu a, jeśli jest już w a. Podobny do operatora set union. Ta funkcja nie zmienia b. Jeśli a = [1,2,3] b = [2,3,4]. Po połączeniu (a, b) tworzy a = [1,2,3,4] i 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]

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.