İki liste arasında fark yaratın


810

Python, bu gibi iki liste var:

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

İkinci listede olmayan ilk listeden öğelerle üçüncü bir liste oluşturmak gerekiyor. Örnek almak gerekir:

temp3 = ['Three', 'Four']

Döngü ve kontrol olmadan hızlı yollar var mı?


14
Elemanlar benzersiz garantili mi? Eğer varsa temp1 = ['One', 'One', 'One']ve temp2 = ['One'], ['One', 'One']geri istiyor musun , ya da []?
Michael Mrozek

@ michael-mrozek benzersizdir.
Max Frai

12
Elemanların sırasını korumak istiyor musunuz?
Mark Byers

Yanıtlar:


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

Dikkat et

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

beklediğiniz / eşit olmasını istediğiniz yer set([1, 3]). Cevabınızı istiyorsanız set([1, 3]), kullanmanız gerekir set([1, 2]).symmetric_difference(set([2, 3])).


27
@Drewdin: Listeler "-" işlenenini desteklemiyor. Bununla birlikte, setler yapar ve yakından bakarsanız yukarıda gösterilen şey.
Godsmith

1
teşekkürler, ben set (ListA) kullanarak sona erdi .symmetric_difference (ListB)
Drewdin

43
simetrik fark şu şekilde yazılabilir: ^ (set1 ^ set2)
Bastian

10
Lütfen, yanıtınızı düzenleyebilir ve bunun yalnızca temp1-temp2 değerini döndürdüğüne işaret edebilir misiniz? .. Diğerlerinin de söylediği gibi tüm farklılıkları geri getirmek için sismetrik farkı kullanmanız gerekir: list (set (temp1) ^ set (temp2))
rkachach

Neden TypeError: 'str' object is not callablebu işlemi yaptığımda alıyorum a = [1,2,2,2,3]veb = [2]
d8aninja

476

Mevcut çözümlerin tümü aşağıdakilerden birini veya diğerini sunar:

  • O (n * m) performansından daha hızlı.
  • Giriş listesinin sırasını koruyun.

Ancak şu ana kadar hiçbir çözümün ikisine de sahip değil. Her ikisini de istiyorsanız, şunu deneyin:

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

Performans testi

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)

Sonuçlar:

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

Siparişi koruduğum ve aynı zamanda düzeni koruduğumda, set çıkarma işleminden de (biraz) daha hızlıdır, çünkü gereksiz bir setin yapılmasını gerektirmez. İlk liste ikinciden önemli ölçüde uzunsa ve karma pahalıysa performans farkı daha belirgin olur. İşte bunu gösteren ikinci bir test:

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

Sonuçlar:

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

2
Bu yanıt için ek destek: Liste sırasını korumanın performans için önemli olduğu bir kullanım senaryosuyla karşılaştık. Tarinfo veya zipinfo nesneleri ile çalışırken set çıkarma kullanıyordum. Belirli tarinfo nesnelerinin arşivden çıkarılmasını engellemek için. Yeni listeyi oluşturmak hızlıydı ancak çıkartma sırasında süper yavaştı. Nedeni ilk başta beni atlattı. Tarinfo nesneleri listesinin yeniden sıralanması büyük bir performans cezasına neden oldu. Liste anlama yöntemine geçmek günü kurtardı.
Ray Thompson

@MarkByers - belki de bunun için tamamen yeni bir soru yazmalıyım. Ama bu bir forloopta nasıl çalışır? Örneğin, benim temp1 ve temp2 sürekli değişiyor .. ve ben yeni bilgileri temp3 eklemek istiyorum?
Ason

@MarkByers - kulağa hoş geliyor. Biraz düşünmeye devam edeceğim. ama harika bir çözüm için +1.
Ason

@Dejel >>> temp1 = ['Bir', 'İki', 'Üç', 'Dört'] >>> temp2 = ['Bir', 'İki', 'Altı'] >>> s = set (temp2) >>> temp3 = [x, s içinde değilse x1 için x] ]> temp3 ['Üç', 'Dört']
kulaktan jöleler

3
@haccks Bir listenin üyeliğini denetlemek O (n) işlemidir (tüm liste üzerinde yineleme), ancak bir kümenin üyeliğini denetlemek O (1) 'dir.
Mark Byers

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

15
Daha temp2önce bir sete dönüştürmek bunu biraz daha verimli hale getirecektir.
lunaryorn

3
Doğru, Ockonal kopyaları önemsiyor ya da etmiyor bağlıdır (orijinal soru söylemez)
matt b

2
Yorum, (listeler | tuples) kopyalarının olmadığını söylüyor.

1
Cevabınızı iptal ettim çünkü ilk başta kopyalar hakkında haklı olduğunuzu düşündüm. Ama item not in temp2ve item not in set(temp2)çiftleri veya olmayan varsa bakılmaksızın her zaman aynı sonuçları döndürür temp2.
arekolek

5
Liste öğelerinin yıkanabilir olmasını gerektirmeyenler için oy verin.
Brent

23

İki liste (diyelim liste1 ve liste2) arasındaki fark, aşağıdaki basit işlev kullanılarak bulunabilir.

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)

veya

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

Yukarıdaki fonksiyonunu kullanarak, fark kullanılarak bulunabilir diff(temp2, temp1)ya da diff(temp1, temp2). Her ikisi de sonucu verecektir ['Four', 'Three']. Listenin sırası veya önce hangi listenin verileceği konusunda endişelenmenize gerek yoktur.

Python doc referansı


7
Neden set (list1) .symmetric_difference (set (list2))?
swietyy

20

Farkı tekrar tekrar istiyorsanız, python için bir paket yazdım: https://github.com/seperman/deepdiff

Kurulum

PyPi'den yükle:

pip install deepdiff

Örnek kullanım

içe

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

Aynı nesne boş döner

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

Bir öğenin türü değişti

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

Bir öğenin değeri değişti

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

Öğe eklendi ve / veya kaldırıldı

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

Dize farkı

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

Dize farkı 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

Tür değişikliği

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

Liste farkı

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

Liste farkı 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}}}

Sıra veya yinelenenleri yok sayan liste farkı: (yukarıdakiyle aynı sözlüklerle)

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

Sözlük içeren liste:

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

Setler:

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

İsimli Tuples:

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

Özel nesneler:

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

Nesne özelliği eklendi:

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

20

Python XOR operatörü kullanılarak yapılabilir.

  • Bu, her listedeki kopyaları kaldıracaktır
  • Bu temp1'den temp1 ve temp1'den temp2 farkını gösterecektir.

set(temp1) ^ set(temp2)

çalışıyor, ama neden?
ZakS

en iyi cevap!
Artsiom Praneuski

ne cevap! çok pitonik !!!! şaşırtıcı
toing_toing

18

en basit yol,

set () kullanın . fark (set ())

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

cevap set([1])

liste olarak yazdırabilir,

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

14

Gerçekten performans arıyorsanız, numpy kullanın!

İşte tam not defteri listesi, numpy ve pandalar arasındaki karşılaştırma ile github üzerinde bir öz olarak.

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

resim açıklamasını buraya girin


Bağlantıdaki not defterini ve ekran görüntüsünü güncelledim. Şaşırtıcı bir şekilde pandalar, dahili olarak hashtable'a geçildiğinde bile numpy'den daha yavaştır. Kısmen bunun nedeni int64'e geçiştir.
denfromufa

13

Mevcut çözümlerin hiçbiri bir tuple vermediği için fırlatacağım:

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

alternatif olarak:

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

Bu yöndeki diğer tuple olmayan cevaplar gibi düzeni korur


11

İki listeleri alacağını ve hangi yapabileceği bir şey istedim diffde bashyapar. "Python diff iki liste" aradığınızda bu soru ilk ortaya çıktığından ve çok spesifik olmadığından, ne bulduğumu yayınlayacağım.

Kullanılması SequenceMatherdan difflibgibi size iki listeleri karşılaştırabilirsiniz diffyapar. Diğer cevapların hiçbiri size farkın oluştuğu konumu söylemeyecektir, ancak bu cevap vermemektedir. Bazı cevaplar farkı sadece tek bir yönde verir. Bazıları öğeleri yeniden sıralar. Bazıları kopyaları işlemez. Ancak bu çözüm size iki liste arasında gerçek bir fark verir:

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

Bu çıktılar:

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

Tabii ki, başvurunuz diğer cevapların verdiği varsayımları aynen yaparsa, onlardan en fazla yararlanacaksınız. Ancak gerçek bir diffişlevsellik arıyorsanız , o zaman bu gitmek için tek yoldur.

Örneğin, diğer cevapların hiçbiri işleyemez:

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

Ama bunu yapar:

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


10

bu Mark'ın liste kavrayışından bile daha hızlı olabilir:

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

7
Biti from itertools import filterfalseburaya dahil etmek isteyebilir . Ayrıca bunun diğerleri gibi bir dizi döndürmediğini, bir yineleyici döndürdüğünü unutmayın.
Matt Luongo

7

İşte en Counterbasit durumun cevabı.

Bu, iki yönlü farklar yapandan daha kısadır, çünkü yalnızca sorunun sorduğunu tam olarak yapar: ilk listede olanın bir listesini oluşturun, ancak ikinci değil.

from collections import Counter

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

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

Alternatif olarak, okunabilirlik tercihlerinize bağlı olarak, iyi bir tek astar sağlar:

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

Çıktı:

['Three', 'Four']

list(...)Yalnızca üzerinden yineleme yapıyorsanız çağrıyı kaldırabileceğinizi unutmayın .

Bu çözüm sayaçları kullandığından, set tabanlı cevapların çoğuna karşı miktarları düzgün bir şekilde işler. Örneğin bu girdide:

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

Çıktı:

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

5

Farklı listenin öğeleri sıralanır ve ayarlanırsa naif bir yöntem kullanabilirsiniz.

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

print list1[len(list2):]

veya yerel ayar yöntemleriyle:

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)

Saf çözüm: 0.0787101593292

Yerel ayar çözümü: 0.998837615564


5

Bunun için oyunda çok geç kaldım, ancak yukarıda belirtilen kodların bazılarının performansıyla bunu karşılaştırabilirsiniz, en hızlı yarışmacılardan ikisi,

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

Temel kodlama düzeyi için özür dilerim.

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

İşte iki dizi dizeyi ayırmanın birkaç basit, siparişi koruyan yolu.

kod

Kullanarak alışılmadık bir yaklaşım 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']

Bu, her iki listenin de eşdeğer başlangıçlı dizeler içerdiğini varsayar. Daha fazla ayrıntı için dokümanlara bakın. Unutmayın, ayarlanan işlemlere kıyasla özellikle hızlı değildir.


Aşağıdakileri kullanan basit bir uygulama itertools.zip_longest:

import itertools as it


[x for x, y in it.zip_longest(temp1, temp2) if x != y]
# ['Three', 'Four']

1
İtertools çözümü yalnızca öğeler çalışır temp1ve temp2çizgi yukarı iyi. Örneğin, öğeleri döndürürseniz temp2veya başında başka bir değer eklerseniz temp2, listcomp yalnızca aynı öğeleri döndürürtemp1
KenHBS

Evet, bu yaklaşımların bir özelliği. Belirtildiği gibi, bu çözümler sipariş korumalıdır - listeler arasında göreceli bir sıralama varsayarlar. Sırasız bir çözüm iki seti birbirinden ayırmak olacaktır.
pylang

4

Bu başka bir çözüm:

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

Diyelim ki iki listemiz var

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

yukarıdaki iki listeden liste2'de 1, 3, 5 öğelerinin var olduğunu ve 7, 9 öğelerinin olmadığını görebilirsiniz. Öte yandan, 1, 3, 5 numaralı öğeler list1'de bulunur ve 2, 4 numaralı öğeler yoktur.

7, 9 ve 2, 4 maddelerini içeren yeni bir liste döndürmek için en iyi çözüm nedir?

Yukarıdaki tüm cevaplar çözümü bulur, şimdi en uygun olanı nedir?

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

karşı

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

Timeit kullanarak sonuçları görebiliriz

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

İadeler

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

Process finished with exit code 0

3

arulmr çözümünün tek satırlı versiyonu

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

3

daha çok bir değişme kümesi gibi ...

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

Kavşak eksi listelerin birleşimini hesaplayabiliriz:

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

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

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

2

Bu bir satır ile çözülebilir. Soruya iki liste verilir (temp1 ve temp2) üçüncü bir listede (temp3) farklarını verir.

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

1

İki listeyi (içerik ne olursa olsun) ayırt etmenin basit bir yolu, sonucu aşağıda gösterildiği gibi alabilirsiniz:

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

Umarım bu yardımcı olacaktır.


0

Setlere dönüştürmeyi ve sonra "fark ()" işlevini kullanmayı tercih ederim. Tam kod:

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

Çıktı:

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

Bu basitçe anlaşılması en kolay olanıdır ve ileride büyük verilerle çalışıyorsanız morover, kümelere dönüştürmek kopyalar gerekli değilse kopyaları kaldıracaktır. Umarım yardımcı olur ;-)


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

3
Cevabı sağlamanın yanı sıra, bu konuya nasıl çalıştığı / uygulandığı hakkında bir açıklama verebilir misiniz? Yanıtlar ve çözümler harika, ancak ayrıntılı kılavuzlar ve açıklamalar çok daha iyi.
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)))

örneğin, eğer list1 = [10, 15, 20, 25, 30, 35, 40]ve list2 = [25, 40, 35]sonra iade edilen listeoutput = [10, 20, 30, 15]


Fark işlemi için bunu yapamazsınız. Tamsayılarda bile, bir işleve 'a - b' gerçekleştirmesini söylerseniz, 'b' 'a'dan büyükse ya da başka bir şekilde olursa olsun,' b 'yi yalnızca' a 'dan çıkarması gerekir. Liste ve kümeler için de durum aynıdır. A - B ve B - A, A ve B uzunluklarından bağımsız olarak geçerli işlemler olabilir, A - B yapmak için B içeriğini A'dan hariç tutmanız yeterlidir.
Abu Talha Danimarka
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.