Ottieni la differenza tra due elenchi


811

Ho due liste in Python, come queste:

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

Devo creare un terzo elenco con elementi del primo elenco che non sono presenti nel secondo. Dall'esempio devo ottenere:

temp3 = ['Three', 'Four']

Esistono modi rapidi senza cicli e controllo?


14
Gli elementi sono garantiti unici? Se hai temp1 = ['One', 'One', 'One']e temp2 = ['One'], vuoi ['One', 'One']indietro o []?
Michael Mrozek, l'

@ michael-mrozek sono unici.
Max Frai,

12
Vuoi preservare l'ordine degli elementi?
Mark Byers,

Risposte:


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

Attenzione

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

dove potresti aspettarti / volere che sia uguale set([1, 3]). Se vuoi set([1, 3])come risposta, dovrai usare set([1, 2]).symmetric_difference(set([2, 3])).


27
@Drewdin: gli elenchi non supportano l'operando "-". Imposta, tuttavia, e ciò che è dimostrato sopra se guardi da vicino.
Godsmith,

1
grazie, ho finito per usare set (ListA) .symmetric_difference (ListB)
Drewdin

43
la differenza simmetrica può essere scritta con: ^ (set1 ^ set2)
Bastian

10
Per favore, potresti modificare la tua risposta e sottolineare che questo restituisce solo temp1-temp2? .. Come altri hanno detto per restituire tutte le differenze devi usare la differenza sysmetric: list (set (temp1) ^ set (temp2))
rkachach

Perché ottengo TypeError: 'str' object is not callablequando a = [1,2,2,2,3]b = [2]
eseguo

478

Le soluzioni esistenti offrono tutte l'una o l'altra di:

  • Prestazioni più veloci di O (n * m).
  • Conserva l'ordine dell'elenco di input.

Ma finora nessuna soluzione ha entrambe. Se vuoi entrambi, prova questo:

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

Test della prestazione

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)

risultati:

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

Il metodo che ho presentato oltre a preservare l'ordine è anche (leggermente) più veloce della sottrazione dell'insieme perché non richiede la costruzione di un insieme non necessario. La differenza di prestazioni sarebbe più evidente se il primo elenco è considerevolmente più lungo del secondo e se l'hashing è costoso. Ecco un secondo test che dimostra questo:

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

risultati:

11.3836875916 # ars' answer
3.63890368748 # this answer (3 times faster!)
37.7445402279 # matt b's answer

2
Supporto aggiuntivo per questa risposta: è stato utilizzato un caso d'uso in cui la conservazione dell'ordine degli elenchi era importante per le prestazioni. Quando lavoravo con oggetti tarinfo o zipinfo stavo usando set sottrazione. Per escludere alcuni oggetti tarinfo dall'estrazione dall'archivio. La creazione del nuovo elenco è stata rapida ma super lenta durante l'estrazione. Il motivo inizialmente mi ha eluso. Risulta che il riordino dell'elenco degli oggetti di tarinfo ha causato un'enorme penalità di prestazione. Passare al metodo di comprensione dell'elenco ha salvato la giornata.
Ray Thompson,

@MarkByers - forse dovrei scrivere una domanda completamente nuova per questo. Ma come avrebbe funzionato in anticipo? Ad esempio, se i miei temp1 e temp2 continuano a cambiare .. e voglio aggiungere le nuove informazioni a temp3?
Ason

@MarkByers - suona bene. Continuerò a pensarci un po '. ma +1 per un'ottima soluzione.
Ason

Sono d'accordo con @Dejel >>> temp1 = ['One', 'Two', 'Three', 'Four'] >>> temp2 = ['One', 'Two', 'Six'] >>> s = set (temp2) >>> temp3 = [x per x in temp1 se x non in s] >>> temp3 ['Three', 'Four']
earlonrails

3
@haccks Perché il controllo dell'appartenenza a un elenco è un'operazione O (n) (ripetendo l'intero elenco), ma il controllo dell'appartenenza a un set è O (1).
Mark Byers,

86
temp3 = [item for item in temp1 if item not in temp2]

15
Trasformarsi temp2in un set prima lo renderebbe un po 'più efficiente.
lunaryorn,

3
Vero, dipende se Ockonal si preoccupa dei duplicati o meno (la domanda originale non dice)
matt b

2
Il commento dice che le (liste | tuple) non hanno duplicati.

1
Ho votato a favore della tua risposta perché all'inizio pensavo che avessi ragione sui duplicati. Ma item not in temp2e item not in set(temp2)restituisce sempre gli stessi risultati, a prescindere se ci sono duplicati o non temp2.
Arekolek,

5
Voto positivo per non richiedere che gli elementi dell'elenco siano hash.
Brent,

23

La differenza tra due liste (diciamo lista1 e lista2) può essere trovata usando la seguente semplice funzione.

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

Usando la funzione sopra, la differenza può essere trovata usando diff(temp2, temp1)o diff(temp1, temp2). Entrambi daranno il risultato ['Four', 'Three']. Non devi preoccuparti dell'ordine della lista o di quale lista deve essere data per prima.

Riferimento doc Python


7
Perché non impostare (list1) .symmetric_difference (set (list2))?
Swietyy,

20

Nel caso in cui desideri la differenza in modo ricorsivo, ho scritto un pacchetto per Python: https://github.com/seperman/deepdiff

Installazione

Installa da PyPi:

pip install deepdiff

Esempio di utilizzo

Importazione

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

Lo stesso oggetto restituisce vuoto

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

Il tipo di un elemento è cambiato

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

Il valore di un articolo è cambiato

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

Articolo aggiunto e / o rimosso

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

Differenza di stringa

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

Differenza di stringa 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

Modifica del 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]}}}

Elenco differenza

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

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

Elenca la differenza ignorando l'ordine o i duplicati: (con gli stessi dizionari di cui sopra)

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

Elenco che contiene il dizionario:

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

Imposta:

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

Tuple nominate:

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

Oggetti personalizzati:

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

Attributo oggetto aggiunto:

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

20

Può essere fatto usando l'operatore python XOR.

  • Ciò rimuoverà i duplicati in ogni elenco
  • Questo mostrerà la differenza di temp1 da temp2 e temp2 da temp1.

set(temp1) ^ set(temp2)

funziona, ma perché?
ZakS

la migliore risposta!
Artsiom Praneuski,

che risposta! così pitonico !!!! fantastico
toing_toing

18

il modo più semplice,

usa set (). differenza (set ())

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

la risposta è set([1])

può stampare come un elenco,

print list(set(list_a).difference(set(list_b)))


13

mi lancerò perché nessuna delle soluzioni attuali produce una tupla:

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

in alternativa:

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

Come l'altra non tupla che fornisce risposte in questa direzione, conserva l'ordine


11

Volevo qualcosa che avrebbe preso due liste e potrebbe fare quello diffin bashfa. Poiché questa domanda viene visualizzata per prima quando si cerca "due liste di Python diff" e non è molto specifica, pubblicherò ciò che mi è venuto in mente.

Usando SequenceMatherdadifflib te puoi confrontare due liste come difffa. Nessuna delle altre risposte ti dirà la posizione in cui si verifica la differenza, ma questa lo fa. Alcune risposte danno la differenza in una sola direzione. Alcuni riordinano gli elementi. Alcuni non gestiscono i duplicati. Ma questa soluzione ti dà una vera differenza tra due elenchi:

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

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

Naturalmente, se la tua applicazione fa gli stessi presupposti delle altre risposte, ne trarrai maggior beneficio. Ma se stai cercando una vera difffunzionalità, questa è l'unica strada da percorrere.

Ad esempio, nessuna delle altre risposte è stata in grado di gestire:

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

Ma questo fa:

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


10

questo potrebbe essere anche più veloce della comprensione dell'elenco di Mark:

list(itertools.filterfalse(set(temp2).__contains__, temp1))

7
Potrebbe voler includere il from itertools import filterfalsebit qui. Si noti inoltre che questo non restituisce una sequenza come le altre, ma restituisce un iteratore.
Matt Luongo,

7

Ecco una Counterrisposta per il caso più semplice.

Questo è più breve di quello sopra che fa differenze a due vie perché fa esattamente solo quello che la domanda pone: genera un elenco di ciò che è nel primo elenco ma non il secondo.

from collections import Counter

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

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

In alternativa, a seconda delle tue preferenze di leggibilità, crea un decente one-liner:

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

Produzione:

['Three', 'Four']

Nota che puoi rimuovere la list(...)chiamata se stai solo ripetendo.

Poiché questa soluzione utilizza contatori, gestisce correttamente le quantità rispetto alle molte risposte basate su set. Ad esempio su questo input:

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

L'output è:

['Two', 'Two', 'Three', 'Three', 'Four']

5

È possibile utilizzare un metodo ingenuo se gli elementi dell'elenco diff sono ordinati e impostati.

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

print list1[len(list2):]

o con metodi set nativi:

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)

Soluzione ingenua: 0,0787101593292

Soluzione di set nativo: 0.998837615564


5

Sono un po 'troppo tardi nel gioco per questo, ma puoi fare un confronto delle prestazioni di alcuni dei codici sopra menzionati con questo, due dei contendenti più veloci sono,

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

Mi scuso per il livello elementare di codifica.

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

Ecco alcuni semplici modi per preservare l'ordine di diffondere due elenchi di stringhe.

Codice

Un approccio insolito utilizzando 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']

Ciò presuppone che entrambi gli elenchi contengano stringhe con inizi equivalenti. Vedi i documenti per maggiori dettagli. Nota, non è particolarmente veloce rispetto alle operazioni impostate.


Un'implementazione diretta 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 soluzione itertools funziona solo quando gli elementi si allineano temp1e si temp2allineano bene. Se, ad esempio, capovolgi gli elementi temp2o inserisci un altro valore all'inizio di temp2, listcomp restituirà gli stessi elementi ditemp1
KenHBS

Sì, è una caratteristica di questi approcci. Come accennato, queste soluzioni preservano l'ordine - assumono un certo ordine relativo tra le liste. Una soluzione non ordinata sarebbe quella di diff due set.
aprile

4

Questa è un'altra soluzione:

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

Diciamo che abbiamo due liste

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

possiamo vedere dalle due precedenti liste che le voci 1, 3, 5 esistono nella lista2 e le voci 7, 9 no. D'altra parte, gli elementi 1, 3, 5 esistono nell'elenco1 e gli articoli 2, 4 no.

Qual è la soluzione migliore per restituire un nuovo elenco contenente gli articoli 7, 9 e 2, 4?

Tutte le risposte sopra trovano la soluzione, qual è la migliore?

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

contro

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

Usando timeit possiamo vedere i risultati

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

ritorna

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

Process finished with exit code 0

3

versione a linea singola della soluzione arulmr

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

3

se vuoi qualcosa di più simile a un changeset ... potresti usare 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

Possiamo calcolare l'intersezione meno l'unione di elenchi:

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

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

Out: set(['Four', 'Five', 'Three']) 

2

Questo può essere risolto con una riga. Alla domanda vengono fornite due liste (temp1 e temp2) che restituiscono la loro differenza in una terza lista (temp3).

temp3 = list(set(temp1).difference(set(temp2)))

1

Ecco un modo semplice per distinguere due elenchi (qualunque sia il contenuto), è possibile ottenere il risultato come mostrato di seguito:

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

Spero che questo sia utile.


0

Preferisco usare la conversione in set e quindi usare la funzione "differenza ()". Il codice completo è:

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

Produzione:

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

È il più facile da capire e in futuro se lavorerai con dati di grandi dimensioni, convertirli in set rimuoverà i duplicati se non sono necessari duplicati. Spero che sia d'aiuto ;-)


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

3
Oltre a fornire la risposta, puoi fornire una spiegazione su come funziona / si applica a questo particolare problema? Le risposte e le soluzioni sono eccezionali, ma le guide e le spiegazioni dettagliate sono infinitamente migliori.
Busse il

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

ad es. se list1 = [10, 15, 20, 25, 30, 35, 40]e list2 = [25, 40, 35]quindi l'elenco restituito saràoutput = [10, 20, 30, 15]


Non è possibile eseguire questa operazione per un'operazione di differenza. Anche nel caso di numeri interi, se si dice a una funzione di eseguire 'a - b', si suppone che sottragga 'b' solo da 'a', non importa se 'b' è più grande di 'a' o in altro modo. Simile è il caso con elenco e set. A - B e B - A entrambi possono essere operazioni valide a prescindere dalle lunghezze di A e B, è sufficiente escludere il contenuto di B da A per eseguire A - B.
Abu Talha Danese
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.