Combiner deux listes et supprimer les doublons, sans supprimer les doublons dans la liste d'origine

115

J'ai deux listes que je dois combiner où la deuxième liste a tous les doublons de la première liste ignorés. .. Un peu difficile à expliquer, alors laissez-moi vous montrer un exemple de ce à quoi ressemble le code et ce que je veux en conséquence.

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]

Vous remarquerez que le résultat a la première liste, y compris ses deux valeurs "2", mais le fait que second_list a également une valeur supplémentaire de 2 et 5 n'est pas ajouté à la première liste.

Normalement, pour quelque chose comme ça, j'utiliserais des ensembles, mais un ensemble sur first_list purgerait les valeurs en double qu'il a déjà. Je me demande donc simplement quel est le moyen le meilleur / le plus rapide pour réaliser cette combinaison souhaitée.

Merci.

Lee Olayvar
la source
3
Et s'il y avait trois 2 second_list?
balpha
@balpha: Oui, je n'ai pas encore complètement décidé comment je veux gérer cela. C'est quelque chose auquel j'avais pensé, mais laissé de côté étant donné mon indécision sur la question :)
Lee Olayvar

Réponses:

168

Vous devez ajouter à la première liste les éléments de la deuxième liste qui ne figurent pas dans la première - les ensembles sont le moyen le plus simple de déterminer de quels éléments ils sont, comme ceci:

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]

Ou si vous préférez les one-liners 8-)

print(first_list + list(set(second_list) - set(first_list)))
RichieHindle
la source
2
Ou ceci si vous en avez besoin trié: print first_list + sorted (set (second_list) - set (first_list))
hughdbrown
2
List (set (first_list) | set (second_list)) # | est défini intersection voir stackoverflow.com/questions/4674013/…
staticd
1
@staticd: Oui, mais cela donne la mauvaise réponse. Il n'y en a qu'un 2dans votre résultat, alors qu'il devrait y en avoir deux.
RichieHindle
Oups. Vous avez raison. Totalement manqué que la première liste était autorisée en double. : P
statique du
66
resulting_list = list(first_list)
resulting_list.extend(x for x in second_list if x not in resulting_list)
Ned Batchelder
la source
7
Enfin une réponse qui n'implique pas de couler en décors! Gloire.
SuperFamousGuy
4
c'est en fait O (n * m) mais peut être pratique lorsque vous avez une liste de choses non hachables et que les performances ne sont pas un problème
alcuadrado
1
Qu'est-ce que je ne veux pas de dupliqué ni du premier ni du second?
Dejell
Cette technique préserve l'ordre des attributs dans la liste, ce qui n'est pas le cas avec set. 👍
Subhash Bhushan
29

Vous pouvez utiliser des ensembles:

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
la source
Oui merci je l'ai. Cela fonctionnera très bien. resultList = first_list + list (set (second_list) -set (first_list))
Kathiravan Umaidurai
9

Vous pouvez ramener cela à une seule ligne de code si vous utilisez 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
la source
7
first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

print( set( first_list + second_list ) )
Paul Roub
la source
5
resulting_list = first_list + [i for i in second_list if i not in first_list]
Daniel Roseman
la source
1
setify first_list et vous êtes "prêt"
u0b34a0f6ae
La liste résultante ne sera pas triée.
avakar
1
Que faire si je ne veux pas non plus qu'une liste ait des doublons? de cette façon, si une liste a des doublons, ils reviendront
Dejell
5

Le plus simple pour moi est:

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
la source
1
C'est une excellente solution, mais gardez à l'esprit que cela ne fonctionnera pas si nous essayons de créer un ensemble de dictionnaires, par exemple (augmentera TypeError: unhashable type: 'dict')
Lakesare
2

Vous pouvez également combiner les réponses de Ned et de RichieHindle Batchelder pour une moyenne cas O (m + n) algorithme qui préserve l' ordre:

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

Notez que la x in scomplexité dans le pire des cas est O (m) , donc la complexité dans le pire des cas de ce code est toujours O (m * n) .

z0r
la source
0

Cela pourrait aider

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

La fonction union fusionne la deuxième liste dans la première, sans dupliquer un élément de a, s'il est déjà dans a. Similaire à l'opérateur set union. Cette fonction ne change pas b. Si a = [1,2,3] b = [2,3,4]. Après l'union (a, b) fait a = [1,2,3,4] et b = [2,3,4]

VeilEclipse
la source
0

Basé sur la recette :

liste_résultante = liste (set (). union (première_liste, deuxième_liste))

Alon
la source
-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
la source