जवाबों:
set
यदि आप आइटम ऑर्डर या पुनरावृत्ति की परवाह नहीं करते हैं तो उपयोग करें । सूची बोध का उपयोग करें यदि आप करते हैं:
>>> def diff(first, second):
second = set(second)
return [item for item in first if item not in second]
>>> diff(A, B)
[1, 3, 4]
>>> diff(B, A)
[5]
>>>
set
बी को लागू करना हानिरहित है, लेकिन A
मूल के बजाय परिणाम के लिए इसे लागू करना और उपयोग करना A
नहीं है।
यदि आदेश से कोई फर्क नहीं पड़ता है, तो आप बस निर्धारित अंतर की गणना कर सकते हैं:
>>> set([1,2,3,4]) - set([2,5])
set([1, 4, 3])
>>> set([2,5]) - set([1,2,3,4])
set([5])
आप एक कर सकते हैं
list(set(A)-set(B))
तथा
list(set(B)-set(A))
एक लाइन:
diff = lambda l1,l2: [x for x in l1 if x not in l2]
diff(A,B)
diff(B,A)
या:
diff = lambda l1,l2: filter(lambda x: x not in l2, l1)
diff(A,B)
diff(B,A)
उपरोक्त उदाहरणों ने मतभेदों की गणना की समस्या को तुच्छ बताया। छंटाई या डी-डुप्लिकेट मानने से निश्चित रूप से अंतर की गणना करना आसान हो जाता है, लेकिन यदि आपकी तुलना उन मान्यताओं को बर्दाश्त नहीं कर सकती है, तो आपको एक अलग एल्गोरिथ्म के गैर-तुच्छ कार्यान्वयन की आवश्यकता होगी। अजगर मानक पुस्तकालय में डिफ्लिब देखें।
from difflib import SequenceMatcher
squeeze=SequenceMatcher( None, A, B )
print "A - B = [%s]"%( reduce( lambda p,q: p+q,
map( lambda t: squeeze.a[t[1]:t[2]],
filter(lambda x:x[0]!='equal',
squeeze.get_opcodes() ) ) ) )
ए - बी = [[१, ३, ४]]
print
कि एक कमांड से एक फ़ंक्शन में बदल गया है, और reduce
, filter
और map
इसे अनफ़िथोनिक घोषित किया गया है। (और मुझे लगता है कि गुइडो सही हो सकता है - मुझे समझ में नहीं आता कि क्या reduce
करता है, या तो।)
पायथन 2.7.3 (डिफ़ॉल्ट, 27 फरवरी 2014, 19:58:35) - आईपीथॉन 1.1.0 - समय: ( गीथूब जिस्ट )
def diff(a, b):
b = set(b)
return [aa for aa in a if aa not in b]
def set_diff(a, b):
return list(set(a) - set(b))
diff_lamb_hension = lambda l1,l2: [x for x in l1 if x not in l2]
diff_lamb_filter = lambda l1,l2: filter(lambda x: x not in l2, l1)
from difflib import SequenceMatcher
def squeezer(a, b):
squeeze = SequenceMatcher(None, a, b)
return reduce(lambda p,q: p+q, map(
lambda t: squeeze.a[t[1]:t[2]],
filter(lambda x:x[0]!='equal',
squeeze.get_opcodes())))
परिणाम:
# Small
a = range(10)
b = range(10/2)
timeit[diff(a, b)]
100000 loops, best of 3: 1.97 µs per loop
timeit[set_diff(a, b)]
100000 loops, best of 3: 2.71 µs per loop
timeit[diff_lamb_hension(a, b)]
100000 loops, best of 3: 2.1 µs per loop
timeit[diff_lamb_filter(a, b)]
100000 loops, best of 3: 3.58 µs per loop
timeit[squeezer(a, b)]
10000 loops, best of 3: 36 µs per loop
# Medium
a = range(10**4)
b = range(10**4/2)
timeit[diff(a, b)]
1000 loops, best of 3: 1.17 ms per loop
timeit[set_diff(a, b)]
1000 loops, best of 3: 1.27 ms per loop
timeit[diff_lamb_hension(a, b)]
1 loops, best of 3: 736 ms per loop
timeit[diff_lamb_filter(a, b)]
1 loops, best of 3: 732 ms per loop
timeit[squeezer(a, b)]
100 loops, best of 3: 12.8 ms per loop
# Big
a = xrange(10**7)
b = xrange(10**7/2)
timeit[diff(a, b)]
1 loops, best of 3: 1.74 s per loop
timeit[set_diff(a, b)]
1 loops, best of 3: 2.57 s per loop
timeit[diff_lamb_filter(a, b)]
# too long to wait for
timeit[diff_lamb_filter(a, b)]
# too long to wait for
timeit[diff_lamb_filter(a, b)]
# TypeError: sequence index must be integer, not 'slice'
@ रोमन-बोडनार्चुक लिस्ट कॉम्प्रिहेंशन फंक्शन डिफ डिफरेंस (ए, बी) तेजी से लगता है।
A = [1,2,3,4]
B = [2,5]
#A - B
x = list(set(A) - set(B))
#B - A
y = list(set(B) - set(A))
print x
print y
आप एक के set
बजाय एक का उपयोग करना चाहते हैं list
।
यदि आप चाहते हैं कि अंतर आपकी सूची के मदों में गहराई से जा रहा है, तो मैंने अजगर के लिए एक पैकेज लिखा है: https://github.com/erasmose/deepdiff
PyPi से स्थापित करें:
pip install deepdiff
यदि आप Python3 हैं तो आपको भी स्थापित करने की आवश्यकता है:
pip install future six
>>> from deepdiff import DeepDiff
>>> from pprint import pprint
>>> from __future__ import print_function
वही वस्तु खाली लौटती है
>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = t1
>>> ddiff = DeepDiff(t1, t2)
>>> print (ddiff.changes)
{}
एक आइटम का प्रकार बदल गया है
>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:"2", 3:3}
>>> ddiff = DeepDiff(t1, t2)
>>> print (ddiff.changes)
{'type_changes': ["root[2]: 2=<type 'int'> vs. 2=<type 'str'>"]}
किसी आइटम का मान बदल गया है
>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:4, 3:3}
>>> ddiff = DeepDiff(t1, t2)
>>> print (ddiff.changes)
{'values_changed': ['root[2]: 2 ====>> 4']}
आइटम जोड़ा गया और / या हटा दिया गया
>>> 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.changes)
{'dic_item_added': ['root[5, 6]'],
'dic_item_removed': ['root[4]'],
'values_changed': ['root[2]: 2 ====>> 4']}
स्ट्रिंग अंतर
>>> 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.changes, indent = 2)
{ 'values_changed': [ 'root[2]: 2 ====>> 4',
"root[4]['b']:\n--- \n+++ \n@@ -1 +1 @@\n-world\n+world!"]}
>>>
>>> print (ddiff.changes['values_changed'][1])
root[4]['b']:
---
+++
@@ -1 +1 @@
-world
+world!
स्ट्रिंग अंतर २
>>> 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.changes, indent = 2)
{ 'values_changed': [ "root[4]['b']:\n--- \n+++ \n@@ -1,5 +1,4 @@\n-world!\n-Goodbye!\n+world\n 1\n 2\n End"]}
>>>
>>> print (ddiff.changes['values_changed'][0])
root[4]['b']:
---
+++
@@ -1,5 +1,4 @@
-world!
-Goodbye!
+world
1
2
End
प्रकार बदलें
>>> 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.changes, indent = 2)
{ 'type_changes': [ "root[4]['b']: [1, 2, 3]=<type 'list'> vs. world\n\n\nEnd=<type 'str'>"]}
सूची का अंतर
>>> 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, 2]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff.changes, indent = 2)
{ 'list_removed': ["root[4]['b']: [3]"]}
सूची अंतर 2: ध्यान दें कि यह आदेश को ध्यान में नहीं रखता है
>>> # Note that it DOES NOT take order into account
... 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]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff.changes, indent = 2)
{ }
उस सूची में शब्दकोश शामिल हैं:
>>> 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.changes, indent = 2)
{ 'dic_item_removed': ["root[4]['b'][2][2]"],
'values_changed': ["root[4]['b'][2][1]: 1 ====>> 3"]}
सबसे सरल तरीका,
सेट का उपयोग करें ()। अंतर (सेट)
list_a = [1,2,3]
list_b = [2,3]
print set(list_a).difference(set(list_b))
जवाब है set([1])
शब्दकोशों की एक सूची के मामले में , पूरी सूची समझने वाला समाधान काम करता है जबकि set
समाधान उठाता है
TypeError: unhashable type: 'dict'
def diff(a, b):
return [aa for aa in a if aa not in b]
d1 = {"a":1, "b":1}
d2 = {"a":2, "b":2}
d3 = {"a":3, "b":3}
>>> diff([d1, d2, d3], [d2, d3])
[{'a': 1, 'b': 1}]
>>> diff([d1, d2, d3], [d1])
[{'a': 2, 'b': 2}, {'a': 3, 'b': 3}]
जब इन-ऑपरेटर के TimeComplexity को देखते हैं , तो सबसे खराब स्थिति में यह O (n) के साथ काम करता है। यहां तक कि सेट्स के लिए भी।
इसलिए जब दो सरणियों की तुलना करते हैं तो हमारे पास सबसे अच्छे मामले में O (n) का TimeComplexity और सबसे खराब स्थिति में O (n ^ 2) होगा।
एक वैकल्पिक (लेकिन दुर्भाग्य से अधिक जटिल) समाधान, जो ओ (एन) के साथ काम करता है सबसे अच्छा और सबसे खराब स्थिति में यह एक है:
# Compares the difference of list a and b
# uses a callback function to compare items
def diff(a, b, callback):
a_missing_in_b = []
ai = 0
bi = 0
a = sorted(a, callback)
b = sorted(b, callback)
while (ai < len(a)) and (bi < len(b)):
cmp = callback(a[ai], b[bi])
if cmp < 0:
a_missing_in_b.append(a[ai])
ai += 1
elif cmp > 0:
# Item b is missing in a
bi += 1
else:
# a and b intersecting on this item
ai += 1
bi += 1
# if a and b are not of same length, we need to add the remaining items
for ai in xrange(ai, len(a)):
a_missing_in_b.append(a[ai])
return a_missing_in_b
जैसे
>>> a=[1,2,3]
>>> b=[2,4,6]
>>> diff(a, b, cmp)
[1, 3]
set(b)
थीटा (n ^ 2) के बजाय एल्गोरिथ्म हे (nlogn) सुनिश्चित करने के लिए उपयोग करने पर विचार करें