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.


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

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)

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]

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]

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

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 .


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]


0

Basierend auf dem Rezept :

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


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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.