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?


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


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

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]

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


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

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)

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

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í


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


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]


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

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

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


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

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

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


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

3

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

def diff(listA, listB):
    return set(listA) - set(listB) | set(listA) -set(listB)

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"

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

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

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.


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


-1
(list(set(a)-set(b))+list(set(b)-set(a)))

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]


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.