Combinar duas listas e remover duplicatas, sem remover duplicatas da lista original


115

Tenho duas listas que preciso combinar, onde a segunda lista tem quaisquer duplicatas da primeira lista ignoradas. .. Um pouco difícil de explicar, então deixe-me mostrar um exemplo de como o código se parece e o que eu quero como resultado.

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]

Você notará que o resultado tem a primeira lista, incluindo seus dois valores "2", mas o fato de que second_list também tem um valor adicional de 2 e 5 não é adicionado à primeira lista.

Normalmente, para algo assim, eu usaria conjuntos, mas um conjunto em first_list limparia os valores duplicados que já possui. Portanto, estou simplesmente imaginando qual é a maneira melhor / mais rápida de conseguir essa combinação desejada.

Obrigado.


3
E se houver três 2s dentro second_list?
balpha

@balpha: Sim, ainda não decidi totalmente como quero lidar com isso. É algo em que pensei, mas deixei de fora devido à minha indecisão sobre o assunto :)
Lee Olayvar

Respostas:


168

Você precisa acrescentar à primeira lista os elementos da segunda lista que não estão na primeira - os conjuntos são a maneira mais fácil de determinar quais elementos eles são, como este:

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 se você preferir one-liners 8-)

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

2
Ou isto se você precisar ordenar: imprimir primeira_lista + ordenada (definir (segunda_lista) - definir (primeira_lista))
hughdbrown

2
List (set (first_list) | set (second_list)) # | é definida a interseção, consulte stackoverflow.com/questions/4674013/…
staticd

1
@staticd: Sim, mas isso dá a resposta errada. Há apenas um 2em seu resultado, quando deveria haver dois deles.
RichieHindle

opa. Você está certo. Totalmente perdido que a primeira lista foi permitido duplicatas. : P
estático em

66
resulting_list = list(first_list)
resulting_list.extend(x for x in second_list if x not in resulting_list)

7
Finalmente, uma resposta que não envolve lançar em conjuntos! Kudos.
SuperFamousGuy

4
na verdade, é O (n * m), mas pode ser útil quando você tem uma lista de itens não hashble e o desempenho não é uma preocupação
alcuadrado

1
O que eu não quero duplicar nem do primeiro nem do segundo?
Dejell

Essa técnica preserva a ordem dos atributos na lista, o que não é o caso com set. 👍
Subhash Bhushan

29

Você pode usar conjuntos:

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]

Sim, obrigado, entendi. Isso vai funcionar bem. resultList = first_list + list (set (second_list) -set (first_list))
Kathiravan Umaidurai

9

Você pode reduzir isso a uma única linha de código se usar 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 e você está "definido"
u0b34a0f6ae

A lista resultante não será classificada.
avakar de

1
E se eu também não quiser que nenhuma lista tenha duplicatas? desta forma, se uma lista tiver duplicatas, eles retornarão
Dejell

5

O mais simples para mim é:

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
Essa é uma ótima solução, mas tenha em mente que não funcionará se tentarmos fazer um conjunto de dicionários em um conjunto, por exemplo, (aumentará TypeError: unhashable type: 'dict')
lagos são de

2

Você também pode combinar as respostas de RichieHindle e Ned Batchelder para um algoritmo O (m + n) de caso médio que preserva a ordem:

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

Observe que x in stem uma complexidade de pior caso de O (m) , então a complexidade de pior caso deste código ainda é O (m * n) .


0

Isso pode ajudar

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

A função de união mescla a segunda lista na primeira, sem duplicar um elemento de a, se já estiver em a. Semelhante a definir operador de união. Esta função não muda b. Se a = [1,2,3] b = [2,3,4]. Após a união (a, b) faz a = [1,2,3,4] e b = [2,3,4]


0

Com base na receita :

resultante_lista = lista (conjunto (). união (primeira_lista, segunda_lista))


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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.