Estoy tratando de encontrar una solución eficiente para el problema posterior:

Tengo varias listas x (número desconocido) con elementos diferentes pero también superpuestos. Me gustaría encontrar los elementos únicos para cada lista y generarlos por separado.

Por ejemplo si tengo 3 listas:

a = [1,2,3,4] 
b = [2,5,6,7]
c = [3,6,8,9]

Esto daría como resultado una salida de (no estoy tratando de encontrar solo los elementos únicos):

a --> [1,4]
b --> [5,7]
c --> [8,9]

Asumiendo que una lista se genera secuencialmente. Estaba pensando en usar conjuntos, pero creo que esto se puede resolver cuando se genera cada lista.

3
Tony.H 7 oct. 2019 a las 13:49

3 respuestas

La mejor respuesta

Aquí hay una solución simple en O (N) donde N es el número total de elementos.

La idea clave es contar para cada elemento cuántas veces aparece en todas las listas. Luego puede filtrar cada lista manteniendo solo los elementos que aparecen una vez.

from collections import Counter

a = [1,2,3,4]
b = [2,5,6,7]
c = [3,6,8,9]

# Count how many times each elements appear.
counter = Counter()

for l in [a,b,c]:
    counter.update(l)

print(counter)

# If an element appears only once, it is an unique element !
for l in [a,b,c]:
    print(*filter(lambda x: counter[x]==1, l))

Y la salida es:

Counter({2: 2, 3: 2, 6: 2, 1: 1, 4: 1, 5: 1, 7: 1, 8: 1, 9: 1})
1 4
5 7
8 9
4
pLOPeGG 7 oct. 2019 a las 11:07

Puede usar un dict que almacena la cantidad de veces que se ve cada número y usarlo para generar un conjunto con el que se comparan las listas. Con el dict significa que no necesita comparar cada lista nueva con todas las demás listas nuevamente (pero duplicate_numbers deberá redefinirse).

tracker_dict = dict()
duplicate_numbers = set()
a = [1,2,3,4] 
b = [2,5,6,7]
c = [3,6,8,9]

# Get count of all numbers in all lists
all_lists = [a, b, c]
for l in all_lists:
    for item in l:
        tracker_dict[item] = tracker_dict.get(item, 0) + 1

# Store all duplicate numbers in a set
duplicate_numbers = set([num for num in tracker_dict if tracker_dict[num] > 1])

# Get new lists
new_a = [i for i in a if i not in duplicate_numbers]

# With a new list that is defined afterwards
d = [1, 4, 5, 1]

# Update the tracker_dict and duplicate_numbers set
for item in d:
    tracker_dict[item] = tracker_dict.get(item, 0) + 1
duplicate_numbers = set([num for num in tracker_dict if tracker_dict[num] > 1])

new_d = [i for i in a if i not in duplicate_numbers]
# This does not affect previously processed lists however
0
Jeremy Hue 7 oct. 2019 a las 11:01

Uso

  • set.difference() - Devuelve un conjunto que contiene los elementos que solo existen en el conjunto x, y no en el conjunto y:

Ej.

a = [1,2,3,4]
b = [2,5,6,7]
c = [3,6,8,9]

abc = list(set(a).difference(b).difference(c))
bca = list(set(b).difference(c).difference(a))
cab = list(set(c).difference(a).difference(b))

print(abc)
print(bca)
print(cab)

O / P:

[1, 4]
[5, 7]
[8, 9]
1
bharatk 7 oct. 2019 a las 10:58
58268059