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.