Łą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.

Lee Olayvar
źródło
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)))
RichieHindle
źródło
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)
Ned Batchelder
źródło
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]
Kathiravan Umaidurai
źródło
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]
mosegui
źródło
7
first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

print( set( first_list + second_list ) )
Paul Roub
źródło
5
resulting_list = first_list + [i for i in second_list if i not in first_list]
Daniel Roseman
źródło
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]
Rafiq
źródło
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) .

z0r
źródło
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]

VeilEclipse
źródło
0

Na podstawie przepisu :

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

Alon
źródło
-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]

user4846254
źródło