Kombinieren von zwei Listen und Entfernen von Duplikaten, ohne Duplikate in der ursprünglichen Liste zu entfernen

115

Ich habe zwei Listen, die ich kombinieren muss, wobei in der zweiten Liste Duplikate der ersten Liste ignoriert werden. .. Ein bisschen schwer zu erklären, also lassen Sie mich ein Beispiel zeigen, wie der Code aussieht und was ich als Ergebnis möchte.

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]

Sie werden feststellen, dass das Ergebnis die erste Liste enthält, einschließlich der beiden "2" -Werte, aber die Tatsache, dass second_list auch einen zusätzlichen Wert von 2 und 5 enthält, wird der ersten Liste nicht hinzugefügt.

Normalerweise würde ich für so etwas Sets verwenden, aber ein Set auf first_list würde die doppelten Werte löschen, die es bereits hat. Ich frage mich also nur, was der beste / schnellste Weg ist, um diese gewünschte Kombination zu erreichen.

Vielen Dank.

Lee Olayvar
quelle
3
Was ist, wenn drei 2er drin sind second_list?
Balpha
@balpha: Ja, ich habe noch nicht ganz entschieden, wie ich damit umgehen will. Es ist etwas, worüber ich nachgedacht hatte, das ich aber aufgrund meiner Unentschlossenheit in dieser Angelegenheit
ausgelassen

Antworten:

168

Sie müssen an die erste Liste die Elemente der zweiten Liste anhängen, die nicht in der ersten Liste enthalten sind. Sätze sind die einfachste Methode, um festzustellen, um welche Elemente es sich handelt:

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]

Oder wenn Sie Einzeiler bevorzugen 8-)

print(first_list + list(set(second_list) - set(first_list)))
RichieHindle
quelle
2
Oder dies, wenn Sie es sortiert benötigen: Drucken Sie first_list + sorted (set (second_list) - set (first_list))
hughdbrown
1
Liste (set (erste_Liste) | set (zweite_Liste)) # | ist Schnittmenge eingestellt siehe stackoverflow.com/questions/4674013/…
staticd
1
@staticd: Ja, aber das gibt die falsche Antwort. Es gibt nur einen 2in Ihrem Ergebnis, wenn es zwei davon geben sollte.
RichieHindle
Hoppla. Du hast recht. Völlig verfehlt , dass die erste Liste wurde Duplikate erlaubt. : 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
quelle
7
Endlich eine Antwort, bei der es nicht darum geht, in Sets zu werfen! Ein großes Lob.
SuperFamousGuy
4
Dies ist in der Tat O (n * m), kann aber nützlich sein, wenn Sie eine Liste von nicht hashbaren Dingen haben und die Leistung kein
Problem darstellt
1
Was möchte ich weder vom ersten noch vom zweiten duplizieren?
Dejell
Diese Technik behält die Reihenfolge der Attribute in der Liste bei, was bei nicht der Fall ist set. 👍
Subhash Bhushan
29

Sie können Sets verwenden:

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
quelle
Ja, danke, ich habe es verstanden. Dies wird gut funktionieren. resultList = first_list + list (set (second_list) -set (first_list))
Kathiravan Umaidurai
9

Sie können dies auf eine einzige Codezeile reduzieren, wenn Sie numpy verwenden:

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
quelle
7
first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

print( set( first_list + second_list ) )
Paul Roub
quelle
5
resulting_list = first_list + [i for i in second_list if i not in first_list]
Daniel Roseman
quelle
1
setify first_list und du bist "set"
u0b34a0f6ae
Die resultierende Liste wird nicht sortiert.
Avakar
1
Was ist, wenn ich auch nicht möchte, dass eine Liste überhaupt Duplikate enthält? Auf diese Weise werden eine Liste mit Duplikaten zurückgegeben
Dejell
5

Am einfachsten für mich ist:

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
quelle
1
Das ist eine großartige Lösung, aber denken Sie daran, dass es nicht funktioniert, wenn wir versuchen, eine Reihe von Wörterbüchern zu einem Satz zu machen, z. B. (wird erhöht TypeError: unhashable type: 'dict')
Lakesare
2

Sie können auch die Antworten von RichieHindle und Ned Batchelder für einen O (m + n) -Algorithmus im Durchschnittsfall kombinieren, der die Reihenfolge beibehält :

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

Beachten Sie, dass O (m)x in s eine Worst-Case-Komplexität aufweist , sodass die Worst-Case- Komplexität dieses Codes immer noch O (m * n) ist .

z0r
quelle
0

Dies könnte helfen

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

Die Vereinigungsfunktion führt die zweite Liste in die erste ein, ohne ein Element von a zu duplizieren, wenn es bereits in a enthalten ist. Ähnlich wie beim Setzen des Gewerkschaftsoperators. Diese Funktion ändert sich nicht. B. Wenn a = [1,2,3] b = [2,3,4]. Nach der Vereinigung (a, b) ergibt sich a = [1,2,3,4] und b = [2,3,4]

VeilEclipse
quelle
0

Basierend auf dem Rezept :

resultierende_Liste = Liste (set (). Union (erste_Liste, zweite_Liste))

Alon
quelle
-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
quelle