Combinare due elenchi e rimuovere i duplicati, senza rimuovere i duplicati nell'elenco originale


115

Ho due elenchi che devo combinare in cui il secondo elenco ha dei duplicati del primo elenco ignorato. .. Un po 'difficile da spiegare, quindi fammi mostrare un esempio di come appare il codice e cosa voglio come risultato.

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]

Noterai che il risultato ha il primo elenco, inclusi i suoi due valori "2", ma il fatto che second_list ha anche un valore 2 e 5 aggiuntivo non viene aggiunto al primo elenco.

Normalmente per qualcosa di simile userei set, ma un set su first_list eliminerebbe i valori duplicati che ha già. Quindi mi chiedo semplicemente quale sia il modo migliore / più veloce per ottenere questa combinazione desiderata.

Grazie.


3
E se ci sono tre 2 second_list?
balpha

@balpha: Sì, non ho ancora deciso come gestirlo. È qualcosa a cui avevo pensato, ma lasciato fuori vista la mia indecisione in merito :)
Lee Olayvar

Risposte:


168

È necessario aggiungere al primo elenco quegli elementi del secondo elenco che non sono nel primo: gli insiemi sono il modo più semplice per determinare quali elementi sono, in questo modo:

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]

O se preferisci una battuta 8-)

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

2
O questo se ne hai bisogno ordinato: stampa first_list + ordinato (set (second_list) - set (first_list))
hughdbrown

2
List (set (first_list) | set (second_list)) # | è insieme intersezione vedere stackoverflow.com/questions/4674013/...
staticd

1
@staticd: Sì, ma questo dà la risposta sbagliata. Ce 2n'è solo uno nel tuo risultato, quando dovrebbero essercene due.
RichieHindle

oops. Hai ragione. Assolutamente mancato che il primo elenco fosse consentito duplicati. : P
staticd

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

7
Finalmente una risposta che non prevede il casting nei set! Complimenti.
SuperFamousGuy

4
questo è in effetti O (n * m) ma può essere utile quando si dispone di un elenco di cose non modificabili e le prestazioni non sono un problema
alcuadrado

1
Cosa non voglio che venga duplicato né dal primo né dal secondo?
Dejell

Questa tecnica conserva l'ordine degli attributi nell'elenco, il che non è il caso di set. 👍
Subhash Bhushan

29

Puoi usare i 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]

Sì, grazie ho capito. Funzionerà bene. resultList = first_list + list (set (second_list) -set (first_list))
Kathiravan Umaidurai

9

Puoi ridurlo a una singola riga di codice se usi 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
imposta first_list e sei "a posto"
u0b34a0f6ae

L'elenco risultante non verrà ordinato.
avakar

1
E se non desidero nemmeno che nessun elenco abbia duplicati? in questo modo se una lista ha duplicati torneranno
Dejell

5

Il più semplice per me è:

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
È un'ottima soluzione, ma tieni presente che non funzionerà se proviamo a rendere un insieme di dizionari un set, ad esempio (solleverà TypeError: unhashable type: 'dict')
lakesare

2

Puoi anche combinare le risposte di RichieHindle e Ned Batchelder per un algoritmo O (m + n) di caso medio che preserva l'ordine:

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

Nota che x in sha una complessità nel caso peggiore di O (m) , quindi la complessità nel caso peggiore di questo codice è ancora O (m * n) .


0

Questo potrebbe aiutare

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

La funzione union unisce la seconda lista alla prima, senza duplicare un elemento di a, se è già in a. Simile a set union operator. Questa funzione non cambia b. Se a = [1,2,3] b = [2,3,4]. Dopo l'unione (a, b) fa a = [1,2,3,4] eb = [2,3,4]


0

Sulla base della ricetta :

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


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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.