2009-08-23 13 views
52

J'ai deux listes que je dois combiner lorsque la deuxième liste contient des doublons de la première liste ignorée. .. Un peu difficile à expliquer, alors laissez-moi montrer un exemple de ce que le code ressemble, et ce que je veux en conséquence.Combinaison de deux listes et suppression des doublons, sans suppression des doublons dans la liste d'origine

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 2 et 5 ne sont pas ajoutés à la première liste.

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

Merci.

+2

Les listes sont-elles toujours triées? – Triptych

+1

Et s'il y a trois 2 dans 'second_list'? – balpha

+0

@balpha: Oui, je n'ai pas encore décidé comment je veux gérer ça. C'est une chose à laquelle j'avais pensé, mais qui a été omise compte tenu de mon indécision :) –

Répondre

95

Vous devez ajouter à la première liste des éléments de la deuxième liste qui ne sont pas dans le premier - ensembles sont la meilleure façon de déterminer 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 one-liners 8-)

print first_list + list(set(second_list) - set(first_list)) 
+2

Ou si vous en avez besoin trié: print first_list + trié (set (second_list) - set (first_list)) – hughdbrown

+0

Liste (set (first_list) | set (second_list)) # | est mis intersection voir http://stackoverflow.com/questions/4674013/how-to-take-two-lists-and-combine-them-excluding-any-duplicates – staticd

+0

@staticd: Oui, mais cela donne une mauvaise réponse. Il n'y a qu'un '2 'dans votre résultat, alors qu'il devrait y en avoir deux. – RichieHindle

3
resulting_list = first_list + [i for i in second_list if i not in first_list] 
+1

définir first_list et vous êtes "set" – u0b34a0f6ae

+0

La liste qui en résulte ne sera pas triée. – avakar

+4

C'est un algorithme O (m * n). – hughdbrown

31
resulting_list = list(first_list) 
resulting_list.extend(x for x in second_list if x not in resulting_list) 
+1

Egalement un algorithme O (m * n). – hughdbrown

+3

Enfin une réponse qui n'implique pas de lancer des ensembles! Gloire. – SuperFamousGuy

+2

c'est en fait O (n * m) mais peut être utile quand vous avez une liste de choses non-ficelables et la performance n'est pas un problème – alcuadrado

1

Cela pourrait aider

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

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

7

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)) 
resultList=[1,2,5,7,9] 
+2

C'est le mauvais résultat. Lisez la question à nouveau. – RichieHindle

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

1

On peut également combiner les réponses pour de RichieHindle et Ned Batchelder pour un average-case 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 x in s has a worst-case complexity of O(m), de sorte que le pire cas complexité de ce code est toujours O (m * n).

1
first_list = [1, 2, 2, 5] 
second_list = [2, 5, 7, 9] 

print(set(first_list + second_list)) 
Questions connexes