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.


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

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)

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]

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]

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

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


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]


0

Basé sur la recette :

liste_résultante = liste (set (). union (première_liste, deuxième_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]

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.