Obtén diferencia entre dos listas

812

Tengo dos listas en Python, como estas:

temp1 = ['One', 'Two', 'Three', 'Four']
temp2 = ['One', 'Two']

Necesito crear una tercera lista con elementos de la primera lista que no están presentes en la segunda. Del ejemplo tengo que obtener:

temp3 = ['Three', 'Four']

¿Hay formas rápidas sin ciclos y comprobaciones?

Max Frai
fuente
14
¿Los elementos garantizados son únicos? Si tiene temp1 = ['One', 'One', 'One']y temp2 = ['One'], ¿quiere ['One', 'One']volver o []?
Michael Mrozek
@ michael-mrozek son únicos.
Max Frai
12
¿Quieres preservar el orden de los elementos?
Mark Byers

Respuestas:

1210
In [5]: list(set(temp1) - set(temp2))
Out[5]: ['Four', 'Three']

Cuidado con eso

In [5]: set([1, 2]) - set([2, 3])
Out[5]: set([1]) 

donde podría esperar / querer que sea igual set([1, 3]). Si quieres set([1, 3])como respuesta, deberás usarla set([1, 2]).symmetric_difference(set([2, 3])).

ars
fuente
27
@Drewdin: las listas no admiten el operando "-". Conjuntos, sin embargo, sí, y eso es lo que se demuestra arriba si se mira de cerca.
Godsmith
1
gracias, terminé usando set (ListA) .symmetric_difference (ListB)
Drewdin
43
la diferencia simétrica se puede escribir con: ^ (set1 ^ set2)
Bastian
10
Por favor, ¿podría editar su respuesta y señalar que esto solo devuelve temp1-temp2? Como dijo otro para devolver todas las diferencias, debe usar la diferencia sistémica: list (set (temp1) ^ set (temp2))
rkachach
¿Por qué TypeError: 'str' object is not callablea = [1,2,2,2,3]b = [2]
aparece
478

Todas las soluciones existentes ofrecen una u otra de:

  • Rendimiento más rápido que O (n * m).
  • Preservar el orden de la lista de entrada.

Pero hasta ahora ninguna solución tiene ambas. Si quieres ambos, prueba esto:

s = set(temp2)
temp3 = [x for x in temp1 if x not in s]

Prueba de rendimiento

import timeit
init = 'temp1 = list(range(100)); temp2 = [i * 2 for i in range(50)]'
print timeit.timeit('list(set(temp1) - set(temp2))', init, number = 100000)
print timeit.timeit('s = set(temp2);[x for x in temp1 if x not in s]', init, number = 100000)
print timeit.timeit('[item for item in temp1 if item not in temp2]', init, number = 100000)

Resultados:

4.34620224079 # ars' answer
4.2770634955  # This answer
30.7715615392 # matt b's answer

El método que presenté, así como el orden de preservación, también es (ligeramente) más rápido que la sustracción del conjunto porque no requiere la construcción de un conjunto innecesario. La diferencia de rendimiento sería más notable si la primera lista es considerablemente más larga que la segunda y si el hashing es costoso. Aquí hay una segunda prueba que demuestra esto:

init = '''
temp1 = [str(i) for i in range(100000)]
temp2 = [str(i * 2) for i in range(50)]
'''

Resultados:

11.3836875916 # ars' answer
3.63890368748 # this answer (3 times faster!)
37.7445402279 # matt b's answer
Mark Byers
fuente
2
Soporte adicional para esta respuesta: se encontró con un caso de uso en el que preservar el orden de la lista era importante para el rendimiento. Cuando trabajaba con objetos tarinfo o zipinfo, estaba usando la resta de conjuntos. Para excluir ciertos objetos tarinfo de ser extraídos del archivo. Crear la nueva lista fue rápido pero súper lento durante la extracción. La razón me evadió al principio. Resulta que reordenar la lista de objetos de tarinfo causó una gran penalización de rendimiento. Cambiar al método de comprensión de la lista salvó el día.
Ray Thompson
@ MarkByers: tal vez debería escribir una pregunta completamente nueva para esto. Pero, ¿cómo funcionaría esto en un forloop? Por ejemplo, si mi temp1 y temp2 siguen cambiando ... y quiero agregar la nueva información a temp3?
Ason el
@MarkByers - suena bien. Seguiré pensando en eso por un momento. pero +1 para una gran solución.
Ason el
Estoy de acuerdo con @Dejel >>> temp1 = ['One', 'Two', 'Three', 'Four'] >>> temp2 = ['One', 'Two', 'Six'] >>> s = conjunto (temp2) >>> TEMP3 = [x para x en temp1 si X no en s] >>> TEMP3 [ 'Tres', 'Four']
earlonrails
3
@haccks Porque verificar la pertenencia a una lista es una operación O (n) (iterar sobre la lista completa), pero verificar la pertenencia de un conjunto es O (1).
Mark Byers
86
temp3 = [item for item in temp1 if item not in temp2]
mate b
fuente
15
Convertirse temp2en un conjunto antes haría esto un poco más eficiente.
lunaryorn
3
Es cierto, depende de si a Ockonal le importan los duplicados o no (la pregunta original no dice)
matt b
2
El comentario dice que las (listas | tuplas) no tienen duplicados.
1
Voté tu respuesta porque pensé que al principio tenías razón sobre los duplicados. Pero item not in temp2y item not in set(temp2)siempre devolverá los mismos resultados, independientemente de si hay duplicados o no temp2.
arekolek
55
Voto ascendente por no requerir que los elementos de la lista sean hashable.
Brent
23

La diferencia entre dos listas (digamos list1 y list2) se puede encontrar usando la siguiente función simple.

def diff(list1, list2):
    c = set(list1).union(set(list2))  # or c = set(list1) | set(list2)
    d = set(list1).intersection(set(list2))  # or d = set(list1) & set(list2)
    return list(c - d)

o

def diff(list1, list2):
    return list(set(list1).symmetric_difference(set(list2)))  # or return list(set(list1) ^ set(list2))

Al usar la función anterior, la diferencia se puede encontrar usando diff(temp2, temp1)o diff(temp1, temp2). Ambos darán el resultado ['Four', 'Three']. No tiene que preocuparse por el orden de la lista o qué lista se debe dar primero.

Referencia de documento de Python

arulmr
fuente
77
¿Por qué no establecer (list1) .symmetric_difference (set (list2))?
elegante el
20

En caso de que desee la diferencia de forma recursiva, he escrito un paquete para python: https://github.com/seperman/deepdiff

Instalación

Instalar desde PyPi:

pip install deepdiff

Ejemplo de uso

Importador

>>> from deepdiff import DeepDiff
>>> from pprint import pprint
>>> from __future__ import print_function # In case running on Python 2

El mismo objeto vuelve vacío

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = t1
>>> print(DeepDiff(t1, t2))
{}

El tipo de un artículo ha cambiado

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:"2", 3:3}
>>> pprint(DeepDiff(t1, t2), indent=2)
{ 'type_changes': { 'root[2]': { 'newtype': <class 'str'>,
                                 'newvalue': '2',
                                 'oldtype': <class 'int'>,
                                 'oldvalue': 2}}}

El valor de un artículo ha cambiado

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:4, 3:3}
>>> pprint(DeepDiff(t1, t2), indent=2)
{'values_changed': {'root[2]': {'newvalue': 4, 'oldvalue': 2}}}

Artículo agregado y / o eliminado

>>> t1 = {1:1, 2:2, 3:3, 4:4}
>>> t2 = {1:1, 2:4, 3:3, 5:5, 6:6}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff)
{'dic_item_added': ['root[5]', 'root[6]'],
 'dic_item_removed': ['root[4]'],
 'values_changed': {'root[2]': {'newvalue': 4, 'oldvalue': 2}}}

Diferencia de cadena

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world"}}
>>> t2 = {1:1, 2:4, 3:3, 4:{"a":"hello", "b":"world!"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'values_changed': { 'root[2]': {'newvalue': 4, 'oldvalue': 2},
                      "root[4]['b']": { 'newvalue': 'world!',
                                        'oldvalue': 'world'}}}

Diferencia de cuerda 2

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world!\nGoodbye!\n1\n2\nEnd"}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n1\n2\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'values_changed': { "root[4]['b']": { 'diff': '--- \n'
                                                '+++ \n'
                                                '@@ -1,5 +1,4 @@\n'
                                                '-world!\n'
                                                '-Goodbye!\n'
                                                '+world\n'
                                                ' 1\n'
                                                ' 2\n'
                                                ' End',
                                        'newvalue': 'world\n1\n2\nEnd',
                                        'oldvalue': 'world!\n'
                                                    'Goodbye!\n'
                                                    '1\n'
                                                    '2\n'
                                                    'End'}}}

>>> 
>>> print (ddiff['values_changed']["root[4]['b']"]["diff"])
--- 
+++ 
@@ -1,5 +1,4 @@
-world!
-Goodbye!
+world
 1
 2
 End

Cambio de tipo

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n\n\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'type_changes': { "root[4]['b']": { 'newtype': <class 'str'>,
                                      'newvalue': 'world\n\n\nEnd',
                                      'oldtype': <class 'list'>,
                                      'oldvalue': [1, 2, 3]}}}

Lista de diferencia

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3, 4]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{'iterable_item_removed': {"root[4]['b'][2]": 3, "root[4]['b'][3]": 4}}

Lista de diferencia 2:

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2, 3]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'iterable_item_added': {"root[4]['b'][3]": 3},
  'values_changed': { "root[4]['b'][1]": {'newvalue': 3, 'oldvalue': 2},
                      "root[4]['b'][2]": {'newvalue': 2, 'oldvalue': 3}}}

Enumere la diferencia ignorando el orden o los duplicados: (con los mismos diccionarios que arriba)

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2, 3]}}
>>> ddiff = DeepDiff(t1, t2, ignore_order=True)
>>> print (ddiff)
{}

Lista que contiene el diccionario:

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:1, 2:2}]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:3}]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'dic_item_removed': ["root[4]['b'][2][2]"],
  'values_changed': {"root[4]['b'][2][1]": {'newvalue': 3, 'oldvalue': 1}}}

Conjuntos

>>> t1 = {1, 2, 8}
>>> t2 = {1, 2, 3, 5}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (DeepDiff(t1, t2))
{'set_item_added': ['root[3]', 'root[5]'], 'set_item_removed': ['root[8]']}

Tuplas nombradas:

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> t1 = Point(x=11, y=22)
>>> t2 = Point(x=11, y=23)
>>> pprint (DeepDiff(t1, t2))
{'values_changed': {'root.y': {'newvalue': 23, 'oldvalue': 22}}}

Objetos personalizados:

>>> class ClassA(object):
...     a = 1
...     def __init__(self, b):
...         self.b = b
... 
>>> t1 = ClassA(1)
>>> t2 = ClassA(2)
>>> 
>>> pprint(DeepDiff(t1, t2))
{'values_changed': {'root.b': {'newvalue': 2, 'oldvalue': 1}}}

Atributo de objeto agregado:

>>> t2.c = "new attribute"
>>> pprint(DeepDiff(t1, t2))
{'attribute_added': ['root.c'],
 'values_changed': {'root.b': {'newvalue': 2, 'oldvalue': 1}}}
Seperman
fuente
20

Se puede hacer usando el operador python XOR.

  • Esto eliminará los duplicados en cada lista
  • Esto mostrará la diferencia de temp1 de temp2 y temp2 de temp1.

set(temp1) ^ set(temp2)
SuperNova
fuente
funciona, pero ¿por qué?
ZakS
la mejor respuesta!
Artsiom Praneuski
que respuesta! tan pitón !!!! increíble
toing_toing
18

de la manera más simple,

use set (). diferencia (set ())

list_a = [1,2,3]
list_b = [2,3]
print set(list_a).difference(set(list_b))

la respuesta es set([1])

puede imprimir como una lista,

print list(set(list_a).difference(set(list_b)))
Mohideen bin Mohammed
fuente
14

Si realmente está buscando rendimiento, ¡use numpy!

Aquí está el cuaderno completo como una esencia de github con comparación entre list, numpy y pandas.

https://gist.github.com/denfromufa/2821ff59b02e9482be15d27f2bbd4451

ingrese la descripción de la imagen aquí

denfromufa
fuente
Actualicé el cuaderno en el enlace y también la captura de pantalla. Sorprendentemente, los pandas son más lentos que numpy incluso cuando cambian a hashtable internamente. En parte esto puede deberse a la conversión a int64.
denfromufa
13

Voy a tirar porque ninguna de las soluciones actuales produce una tupla:

temp3 = tuple(set(temp1) - set(temp2))

alternativamente:

#edited using @Mark Byers idea. If you accept this one as answer, just accept his instead.
temp3 = tuple(x for x in temp1 if x not in set(temp2))

Al igual que las otras respuestas que no producen tuplas en esta dirección, conserva el orden

aaronasterling
fuente
11

Yo quería algo que llevaría dos listas y podría hacer lo que diffen bashlo hace. Dado que esta pregunta aparece primero cuando busca "python diff two lists" y no es muy específica, publicaré lo que se me ocurrió.

Usando SequenceMatherdesde difflibusted puede comparar dos listas como lo diffhace. Ninguna de las otras respuestas le dirá la posición donde se produce la diferencia, pero esta sí. Algunas respuestas dan la diferencia en una sola dirección. Algunos reordenan los elementos. Algunos no manejan duplicados. Pero esta solución le brinda una verdadera diferencia entre dos listas:

a = 'A quick fox jumps the lazy dog'.split()
b = 'A quick brown mouse jumps over the dog'.split()

from difflib import SequenceMatcher

for tag, i, j, k, l in SequenceMatcher(None, a, b).get_opcodes():
  if tag == 'equal': print('both have', a[i:j])
  if tag in ('delete', 'replace'): print('  1st has', a[i:j])
  if tag in ('insert', 'replace'): print('  2nd has', b[k:l])

Esto produce:

both have ['A', 'quick']
  1st has ['fox']
  2nd has ['brown', 'mouse']
both have ['jumps']
  2nd has ['over']
both have ['the']
  1st has ['lazy']
both have ['dog']

Por supuesto, si su aplicación hace las mismas suposiciones que las otras respuestas, se beneficiará más de ellas. Pero si está buscando una verdadera difffuncionalidad, entonces este es el único camino a seguir.

Por ejemplo, ninguna de las otras respuestas podría manejar:

a = [1,2,3,4,5]
b = [5,4,3,2,1]

Pero este sí:

  2nd has [5, 4, 3, 2]
both have [1]
  1st has [2, 3, 4, 5]
arekolek
fuente
10

Prueba esto:

temp3 = set(temp1) - set(temp2)
Maciej Kucharz
fuente
10

esto podría ser incluso más rápido que la comprensión de la lista de Mark:

list(itertools.filterfalse(set(temp2).__contains__, temp1))
Mahoma
fuente
77
Podría querer incluir el from itertools import filterfalsebit aquí. También tenga en cuenta que esto no devuelve una secuencia como las demás, devuelve un iterador.
Matt Luongo
7

Aquí hay una Counterrespuesta para el caso más simple.

Esto es más corto que el anterior que hace diferencias bidireccionales porque solo hace exactamente lo que la pregunta pregunta: generar una lista de lo que está en la primera lista pero no en la segunda.

from collections import Counter

lst1 = ['One', 'Two', 'Three', 'Four']
lst2 = ['One', 'Two']

c1 = Counter(lst1)
c2 = Counter(lst2)
diff = list((c1 - c2).elements())

Alternativamente, dependiendo de sus preferencias de legibilidad, lo convierte en una línea decente:

diff = list((Counter(lst1) - Counter(lst2)).elements())

Salida:

['Three', 'Four']

Tenga en cuenta que puede eliminar la list(...)llamada si solo está iterando sobre ella.

Debido a que esta solución utiliza contadores, maneja las cantidades correctamente frente a las muchas respuestas basadas en conjuntos. Por ejemplo en esta entrada:

lst1 = ['One', 'Two', 'Two', 'Two', 'Three', 'Three', 'Four']
lst2 = ['One', 'Two']

El resultado es:

['Two', 'Two', 'Three', 'Three', 'Four']
Taylor Edmiston
fuente
5

Podría usar un método ingenuo si los elementos del difflist están ordenados y establecidos.

list1=[1,2,3,4,5]
list2=[1,2,3]

print list1[len(list2):]

o con métodos de configuración nativos:

subset=set(list1).difference(list2)

print subset

import timeit
init = 'temp1 = list(range(100)); temp2 = [i * 2 for i in range(50)]'
print "Naive solution: ", timeit.timeit('temp1[len(temp2):]', init, number = 100000)
print "Native set solution: ", timeit.timeit('set(temp1).difference(temp2)', init, number = 100000)

Solución ingenua: 0.0787101593292

Solución de conjunto nativo: 0.998837615564

sonido
fuente
5

Estoy demasiado tarde en el juego para esto, pero puedes hacer una comparación del rendimiento de algunos de los códigos mencionados anteriormente con esto, dos de los contendientes más rápidos son,

list(set(x).symmetric_difference(set(y)))
list(set(x) ^ set(y))

Pido disculpas por el nivel elemental de codificación.

import time
import random
from itertools import filterfalse

# 1 - performance (time taken)
# 2 - correctness (answer - 1,4,5,6)
# set performance
performance = 1
numberoftests = 7

def answer(x,y,z):
    if z == 0:
        start = time.clock()
        lists = (str(list(set(x)-set(y))+list(set(y)-set(y))))
        times = ("1 = " + str(time.clock() - start))
        return (lists,times)

    elif z == 1:
        start = time.clock()
        lists = (str(list(set(x).symmetric_difference(set(y)))))
        times = ("2 = " + str(time.clock() - start))
        return (lists,times)

    elif z == 2:
        start = time.clock()
        lists = (str(list(set(x) ^ set(y))))
        times = ("3 = " + str(time.clock() - start))
        return (lists,times)

    elif z == 3:
        start = time.clock()
        lists = (filterfalse(set(y).__contains__, x))
        times = ("4 = " + str(time.clock() - start))
        return (lists,times)

    elif z == 4:
        start = time.clock()
        lists = (tuple(set(x) - set(y)))
        times = ("5 = " + str(time.clock() - start))
        return (lists,times)

    elif z == 5:
        start = time.clock()
        lists = ([tt for tt in x if tt not in y])
        times = ("6 = " + str(time.clock() - start))
        return (lists,times)

    else:    
        start = time.clock()
        Xarray = [iDa for iDa in x if iDa not in y]
        Yarray = [iDb for iDb in y if iDb not in x]
        lists = (str(Xarray + Yarray))
        times = ("7 = " + str(time.clock() - start))
        return (lists,times)

n = numberoftests

if performance == 2:
    a = [1,2,3,4,5]
    b = [3,2,6]
    for c in range(0,n):
        d = answer(a,b,c)
        print(d[0])

elif performance == 1:
    for tests in range(0,10):
        print("Test Number" + str(tests + 1))
        a = random.sample(range(1, 900000), 9999)
        b = random.sample(range(1, 900000), 9999)
        for c in range(0,n):
            #if c not in (1,4,5,6):
            d = answer(a,b,c)
            print(d[1])
Alex Jacob
fuente
5

Aquí hay algunos simples, preservar el orden formas de diferenciar dos listas de cadenas.

Código

Un enfoque inusual usando pathlib:

import pathlib


temp1 = ["One", "Two", "Three", "Four"]
temp2 = ["One", "Two"]

p = pathlib.Path(*temp1)
r = p.relative_to(*temp2)
list(r.parts)
# ['Three', 'Four']

Esto supone que ambas listas contienen cadenas con comienzos equivalentes. Ver los documentos para más detalles. Tenga en cuenta que no es particularmente rápido en comparación con las operaciones establecidas.


Una implementación sencilla usando itertools.zip_longest:

import itertools as it


[x for x, y in it.zip_longest(temp1, temp2) if x != y]
# ['Three', 'Four']
pylang
fuente
1
La solución itertools sólo funciona cuando los elementos temp1y temp2se alinean bien. Si, por ejemplo, cambia los elementos temp2o inserta algún otro valor al principio de temp2, la listacomp solo devolverá los mismos elementos que entemp1
KenHBS
Sí, es una característica de estos enfoques. Como se mencionó, estas soluciones preservan el orden: asumen un orden relativo entre las listas. Una solución no ordenada sería diferenciar dos conjuntos.
pylang
4

Esta es otra solución:

def diff(a, b):
    xa = [i for i in set(a) if i not in b]
    xb = [i for i in set(b) if i not in a]
    return xa + xb
manhgd
fuente
4

Digamos que tenemos dos listas

list1 = [1, 3, 5, 7, 9]
list2 = [1, 2, 3, 4, 5]

Podemos ver en las dos listas anteriores que los elementos 1, 3, 5 existen en la lista 2 y los elementos 7, 9 no. Por otro lado, los ítems 1, 3, 5 existen en la lista1 y los ítems 2, 4 no.

¿Cuál es la mejor solución para devolver una nueva lista que contiene los elementos 7, 9 y 2, 4?

Todas las respuestas anteriores encuentran la solución, ¿cuál es la más óptima?

def difference(list1, list2):
    new_list = []
    for i in list1:
        if i not in list2:
            new_list.append(i)

    for j in list2:
        if j not in list1:
            new_list.append(j)
    return new_list

versus

def sym_diff(list1, list2):
    return list(set(list1).symmetric_difference(set(list2)))

Usando timeit podemos ver los resultados

t1 = timeit.Timer("difference(list1, list2)", "from __main__ import difference, 
list1, list2")
t2 = timeit.Timer("sym_diff(list1, list2)", "from __main__ import sym_diff, 
list1, list2")

print('Using two for loops', t1.timeit(number=100000), 'Milliseconds')
print('Using two for loops', t2.timeit(number=100000), 'Milliseconds')

devoluciones

[7, 9, 2, 4]
Using two for loops 0.11572412995155901 Milliseconds
Using symmetric_difference 0.11285737506113946 Milliseconds

Process finished with exit code 0
Carson
fuente
3

versión de línea única de solución arulmr

def diff(listA, listB):
    return set(listA) - set(listB) | set(listA) -set(listB)
pulagam sreemanth
fuente
3

si quieres algo más como un conjunto de cambios ... podrías usar Counter

from collections import Counter

def diff(a, b):
  """ more verbose than needs to be, for clarity """
  ca, cb = Counter(a), Counter(b)
  to_add = cb - ca
  to_remove = ca - cb
  changes = Counter(to_add)
  changes.subtract(to_remove)
  return changes

lista = ['one', 'three', 'four', 'four', 'one']
listb = ['one', 'two', 'three']

In [127]: diff(lista, listb)
Out[127]: Counter({'two': 1, 'one': -1, 'four': -2})
# in order to go from lista to list b, you need to add a "two", remove a "one", and remove two "four"s

In [128]: diff(listb, lista)
Out[128]: Counter({'four': 2, 'one': 1, 'two': -1})
# in order to go from listb to lista, you must add two "four"s, add a "one", and remove a "two"
Nick Franceschina
fuente
2

Podemos calcular la intersección menos la unión de listas:

temp1 = ['One', 'Two', 'Three', 'Four']
temp2 = ['One', 'Two', 'Five']

set(temp1+temp2)-(set(temp1)&set(temp2))

Out: set(['Four', 'Five', 'Three']) 
Mohammad Etemaddar
fuente
2

Esto se puede resolver con una línea. La pregunta se da dos listas (temp1 y temp2) devuelven su diferencia en una tercera lista (temp3).

temp3 = list(set(temp1).difference(set(temp2)))
fgaim
fuente
1

Aquí hay una manera simple de distinguir dos listas (cualquiera que sea el contenido), puede obtener el resultado como se muestra a continuación:

>>> from sets import Set
>>>
>>> l1 = ['xvda', False, 'xvdbb', 12, 'xvdbc']
>>> l2 = ['xvda', 'xvdbb', 'xvdbc', 'xvdbd', None]
>>>
>>> Set(l1).symmetric_difference(Set(l2))
Set([False, 'xvdbd', None, 12])

Espero que esto sea útil.

SK Venkat
fuente
0

Prefiero usar la conversión a conjuntos y luego usar la función "diferencia ()". El código completo es:

temp1 = ['One', 'Two', 'Three', 'Four'  ]                   
temp2 = ['One', 'Two']
set1 = set(temp1)
set2 = set(temp2)
set3 = set1.difference(set2)
temp3 = list(set3)
print(temp3)

Salida:

>>>print(temp3)
['Three', 'Four']

Es el más fácil de entender y, en el futuro, si trabaja con datos grandes, convertirlos en conjuntos eliminará los duplicados si no se requieren duplicados. Espero eso ayude ;-)

Shakhyar Gogoi
fuente
-1
(list(set(a)-set(b))+list(set(b)-set(a)))
nadhem
fuente
3
Además de proporcionar la respuesta, ¿puede dar una explicación de cómo funciona / se aplica a este problema en particular? Las respuestas y las soluciones son excelentes, pero las guías y explicaciones detalladas son infinitamente mejores.
Busse
-1
def diffList(list1, list2):     # returns the difference between two lists.
    if len(list1) > len(list2):
        return (list(set(list1) - set(list2)))
    else:
        return (list(set(list2) - set(list1)))

por ejemplo, si list1 = [10, 15, 20, 25, 30, 35, 40]y list2 = [25, 40, 35]luego la lista devuelta seráoutput = [10, 20, 30, 15]

csg
fuente
No puede hacer esto para la operación de diferencia. Incluso en el caso de los enteros, si le dice a una función que realice 'a - b', se supone que resta 'b' de 'a' solamente, sin importar si 'b' es mayor que 'a' o no. Similar es el caso con la lista y los conjuntos. A - B y B - A pueden ser operaciones válidas independientemente de la longitud de A y B, solo debe excluir el contenido de B de A para realizar A - B.
Abu Talha Danish