दो सूचियों के बीच अंतर प्राप्त करें


809

मेरे पास पायथन में दो सूचियाँ हैं, जैसे:

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

मुझे पहली सूची से आइटम के साथ एक तीसरी सूची बनाने की आवश्यकता है जो दूसरे में मौजूद नहीं है। मुझे प्राप्त होने वाले उदाहरण से:

temp3 = ['Three', 'Four']

क्या साइकिल और जाँच के बिना कोई तेज़ तरीके हैं?


14
क्या तत्वों की गारंटी अद्वितीय है? यदि आपके पास है temp1 = ['One', 'One', 'One']और temp2 = ['One']क्या आप ['One', 'One']वापस चाहते हैं, या []?
माइकल Mrozek

@ माइकल-माज़रेक वे अद्वितीय हैं।
मैक्स फ्राई

12
क्या आप तत्वों के क्रम को संरक्षित करना चाहते हैं?
मार्क बायर्स

जवाबों:


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

उससे सावधान रहें

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

जहाँ आप उम्मीद कर सकते हैं / बराबर करना चाहते हैं set([1, 3])। यदि आप set([1, 3])अपने उत्तर के रूप में चाहते हैं , तो आपको उपयोग करने की आवश्यकता होगी set([1, 2]).symmetric_difference(set([2, 3]))


27
@ ड्र्यूडिन: सूचियाँ "-" ऑपरेंड का समर्थन नहीं करती हैं। सेट, हालांकि, करते हैं, और अगर आप निकट से देखते हैं तो ऊपर जो दिखाया गया है।
गॉडस्मिथ

1
धन्यवाद, मैंने सेट (लिस्ट) (। लिस्ट) का उपयोग कर समाप्त कर दिया। सूची (सूची)
ड्रयूडिन १५'१४ को १२:२०

43
सममित अंतर के साथ लिखा जा सकता है: ^ (सेट 1 ^ सेट 2)
बैस्टियन

10
कृपया, क्या आप अपना उत्तर संपादित कर सकते हैं और यह इंगित कर सकते हैं कि यह केवल temp1-temp2 लौटाता है? .. जैसा कि अन्य ने कहा कि सभी अंतरों को वापस करने के लिए आपको सममितीय अंतर का उपयोग करना होगा: सूची (सेट (temp1) ^ सेट (temp2))
rachachach

TypeError: 'str' object is not callableजब मैं इस ऑपरेशन को करता हूं तो मुझे क्यों मिलता है a = [1,2,2,2,3]औरb = [2]
d8aninja

475

मौजूदा समाधान सभी या तो एक या दूसरे की पेशकश करते हैं:

  • O (n * m) प्रदर्शन से अधिक तेज़।
  • इनपुट सूची का आदेश सुरक्षित रखें।

लेकिन अभी तक दोनों के पास कोई हल नहीं है। यदि आप दोनों चाहते हैं, तो यह कोशिश करें:

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

प्रदर्शन का परीक्षण

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)

परिणाम:

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

मैंने जिस विधि के साथ-साथ संरक्षण के आदेश को प्रस्तुत किया है वह भी सेट घटाव की तुलना में तेज़ (थोड़ा) है क्योंकि इसमें अनावश्यक सेट के निर्माण की आवश्यकता नहीं है। यदि पहली सूची दूसरे की तुलना में काफी लंबी है और यदि हैशिंग महंगी है तो प्रदर्शन अंतर अधिक ध्यान देने योग्य होगा। यहां एक दूसरा परीक्षण दिखाया गया है:

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

परिणाम:

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

2
इस उत्तर के लिए अतिरिक्त समर्थन: उपयोग के मामले में भाग जहां सूची क्रम को संरक्षित करना प्रदर्शन के लिए महत्वपूर्ण था। जब मैं tarinfo या zipinfo ऑब्जेक्ट्स के साथ काम कर रहा था तो मैं सेट घटाव का उपयोग कर रहा था। संग्रह से कुछ टेरिनो ऑब्जेक्ट्स को निकालने के लिए। नई सूची बनाना तेज था लेकिन निष्कर्षण के दौरान सुपर धीमा था। कारण मुझे पहली बार में विकसित किया। Tarinfo ऑब्जेक्ट्स सूची को पुन: व्यवस्थित करने की ओर मुड़ने से भारी प्रदर्शन जुर्माना हुआ। सूची समझने की विधि पर स्विच करने से दिन बच गया।
रे थॉम्पसन

@ मार्कर्स - शायद मुझे इसके लिए एक बिल्कुल नया प्रश्न लिखना चाहिए। लेकिन यह कैसे काम करेगा? उदाहरण के लिए, यदि मेरे temp1 और temp2 बदलते रहें .. और मैं temp3 में नई जानकारी जोड़ना चाहता हूं?
आसन

@ मार्कर्स - अच्छा लगता है। मैं इसके बारे में थोड़ा सोचता रहूंगा। लेकिन एक महान समाधान के लिए +1।
असोन

मैं @ डीजेल >>> टेम्पे 1 = ['वन', 'टू', 'थ्री', 'फोर'] >>> टेंप 2 = ['वन', 'टू', 'सिक्स'] >>> s = से सहमत हूं। set (temp2) >>> temp3 = [x for x in temp1 अगर x s में नहीं] >>> temp3 ['थ्री', 'फोर']
इयरलोनरिल्स

3
@ झटके क्योंकि किसी सूची की सदस्यता की जाँच एक O (n) ऑपरेशन है (संपूर्ण सूची पर पुनरावृत्ति), लेकिन एक सेट की सदस्यता की जाँच O (1) है।
मार्क बायर्स

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

15
temp2पहले सेट में बदल जाने से यह थोड़ा और कुशल हो जाता।
चंद्रोदय

3
सच है, यह निर्भर करता है कि ओक्नोनल नकल के बारे में परवाह करता है या नहीं (मूल सवाल यह नहीं कहता है)
मैट बी

2
टिप्पणी कहती है (सूचियाँ। टुपल्स) में डुप्लिकेट नहीं है।

1
मैंने आपके उत्तर को गलत ठहराया क्योंकि मुझे लगा कि आप पहले डुप्लिकेट के बारे में सही थे। लेकिन item not in temp2और item not in set(temp2)हमेशा वही परिणाम लौटाएंगे, भले ही डुप्लिकेट हों या न हों temp2
इस्कॉलेक

5
सूची के आइटमों को हैश होने की आवश्यकता नहीं है।
ब्रेंट

23

दो सूचियों के बीच अंतर (लिस्ट 1 और लिस्ट 2) निम्नलिखित सरल फ़ंक्शन का उपयोग करके पाया जा सकता है।

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)

या

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

उपरोक्त फ़ंक्शन का उपयोग करके, अंतर का उपयोग करके पाया जा सकता है diff(temp2, temp1)या diff(temp1, temp2)। दोनों ही परिणाम देंगे ['Four', 'Three']। आपको सूची के क्रम के बारे में चिंता करने की जरूरत नहीं है या कौन सी सूची पहले दी जानी है।

पायथन डॉक संदर्भ


7
सेट (सूची 1) क्यों नहीं किया गया है। एसिमेट्रिक_डिफरेंस (सेट (सूची 2))?
स्वैच्छिक 16:15

20

यदि आप अंतर चाहते हैं, तो मैंने अजगर के लिए पैकेज लिखा है: https://github.com/seperman/deepdiff

स्थापना

PyPi से स्थापित करें:

pip install deepdiff

उदाहरण उपयोग

आयात कर रहा है

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

वही वस्तु खाली लौटती है

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

एक आइटम का प्रकार बदल गया है

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

किसी आइटम का मान बदल गया है

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

आइटम जोड़ा गया और / या हटा दिया गया

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

स्ट्रिंग अंतर

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

स्ट्रिंग अंतर २

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

प्रकार बदलें

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

सूची का अंतर

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

सूची अंतर 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}}}

आदेश या डुप्लिकेट की अनदेखी अंतर सूची: (ऊपर के रूप में एक ही शब्दकोश के साथ)

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

उस सूची में शब्दकोश शामिल हैं:

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

सेट:

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

नामित टुपल्स:

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

कस्टम ऑब्जेक्ट:

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

ऑब्जेक्ट विशेषता जोड़ी गई:

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

20

अजगर एक्सओआर ऑपरेटर का उपयोग करके किया जा सकता है।

  • यह प्रत्येक सूची में डुप्लिकेट को हटा देगा
  • यह temp1 से temp1 और temp2 से temp2 का अंतर दिखाएगा।

set(temp1) ^ set(temp2)

काम करता है, लेकिन क्यों?
ज़कस

सबसे अच्छा जवाब!
आर्टिसिओम प्रांशुस्की

क्या जवाब है! इतना अजगर !! अद्भुत
toing_toing

18

सबसे सरल तरीका,

सेट का उपयोग करें ()। अंतर (सेट)

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

जवाब है set([1])

सूची के रूप में प्रिंट कर सकते हैं,

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

14

यदि आप वास्तव में प्रदर्शन में दिख रहे हैं, तो सुन्न का उपयोग करें!

यहाँ सूची, सुन्न और पंडों के बीच तुलना के साथ जीथब पर एक मुट्ठी के रूप में पूर्ण नोटबुक है।

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

यहां छवि विवरण दर्ज करें


मैंने लिंक में नोटबुक को अपडेट किया और स्क्रीनशॉट भी। आंतरिक रूप से हैशटेबल पर स्विच करते समय आश्चर्यजनक रूप से पांडा सुस्ती से भी धीमी होती है। आंशिक रूप से यह int64 तक की वजह से हो सकता है।
denfromufa

13

मैं वर्तमान समाधानों में से किसी में भी टॉस करूँगा, टॉस करूँगा:

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

वैकल्पिक रूप से:

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

इस दिशा में अन्य नॉन-ट्यूपल पैदावार के उत्तर की तरह, यह ऑर्डर को संरक्षित करता है


11

मैं कुछ है कि दो सूचियों ले जाएगा और क्या कर सकता है चाहता था diffमें bashकरता है। चूँकि यह सवाल पहले उठता है जब आप "अजगर दो सूचियाँ अलग करते हैं" और बहुत विशिष्ट नहीं होते हैं, तो मैं वही पोस्ट करूँगा जो मैं लेकर आया था।

का प्रयोग SequenceMatherसे difflibआप दो सूचियों की तुलना कर सकते की तरह diffकरता है। अन्य उत्तरों में से कोई भी आपको वह स्थिति नहीं बताएगा जहां अंतर होता है, लेकिन यह एक करता है। कुछ उत्तर केवल एक दिशा में अंतर देते हैं। कुछ तत्वों को पुनः व्यवस्थित करते हैं। कुछ डुप्लिकेट संभाल नहीं है। लेकिन यह समाधान आपको दो सूचियों के बीच एक वास्तविक अंतर देता है:

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

यह आउटपुट:

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

बेशक, यदि आपका आवेदन वही अनुमान लगाता है जो अन्य उत्तर बनाते हैं, तो आपको उनसे सबसे अधिक लाभ होगा। लेकिन अगर आप एक सच्ची diffकार्यक्षमता की तलाश में हैं, तो यह एकमात्र रास्ता है।

उदाहरण के लिए, कोई भी अन्य जवाब नहीं दे सका:

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

लेकिन यह एक करता है:

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


10

यह मार्क की सूची की समझ से भी तेज हो सकता है:

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

7
from itertools import filterfalseयहाँ बिट को शामिल करना चाह सकते हैं । यह भी ध्यान दें कि यह दूसरों की तरह एक अनुक्रम नहीं लौटाता है, यह एक पुनरावृत्त लौटाता है।
मैट लूंगो

7

यहाँ Counterसबसे सरल मामले के लिए एक जवाब है।

यह ऊपर वाले की तुलना में छोटा है जो दो-तरफ़ा करता है क्योंकि यह केवल वही करता है जो सवाल पूछता है: पहली सूची में क्या है, लेकिन दूसरी नहीं।

from collections import Counter

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

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

वैकल्पिक रूप से, आपकी पठनीयता की प्राथमिकताओं के आधार पर, यह एक अच्छे वन-लाइनर के लिए बनाता है:

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

आउटपुट:

['Three', 'Four']

ध्यान दें कि आप list(...)कॉल को निकाल सकते हैं यदि आप इस पर केवल पुनरावृत्ति कर रहे हैं।

क्योंकि यह समाधान काउंटरों का उपयोग करता है, यह कई सेट-आधारित उत्तरों के ठीक से मात्रा को संभालता है। इस इनपुट पर उदाहरण के लिए:

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

आउटपुट है:

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

5

यदि एक अलग विधि का उपयोग किया जाता है, तो आप एक भोली विधि का उपयोग कर सकते हैं।

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

print list1[len(list2):]

या देशी सेट विधियों के साथ:

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)

Naive solution: 0.0787101593292

देशी सेट समाधान: 0.998837615564


5

मुझे इसके लिए खेल में बहुत देर हो गई है लेकिन आप उपर्युक्त कुछ कोड के प्रदर्शन की तुलना इसके साथ कर सकते हैं, दो सबसे तेज दावेदार हैं,

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

मैं कोडिंग के प्राथमिक स्तर के लिए माफी माँगता हूँ।

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

यहाँ कुछ सरल, क्रम-संरक्षण हैंस्ट्रिंग्स की दो सूचियों को अलग तरीके ।

कोड

एक असामान्य दृष्टिकोण का उपयोग 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']

यह मानता है कि दोनों सूचियों में समतुल्य शुरुआत के साथ तार हैं। देखें डॉक्स अधिक जानकारी के लिए। ध्यान दें, यह निर्धारित कार्यों की तुलना में विशेष रूप से तेज़ नहीं है।


एक सीधे आगे कार्यान्वयन का उपयोग कर itertools.zip_longest:

import itertools as it


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

1
Itertools समाधान केवल तब काम करता है जब तत्वों को अच्छी तरह से temp1और temp2लाइन में। यदि आप, उदाहरण के लिए, तत्वों के चारों ओर मुड़ते हैं temp2या शुरुआत में कुछ अन्य मूल्य सम्मिलित करते हैं temp2, तो सूचीबद्घ उसी तत्वों को वापस लौटा देगा जैसेtemp1
केनहबीएस

हां, यह इन तरीकों की एक विशेषता है। जैसा कि उल्लेख किया गया है, ये समाधान आदेश संरक्षण हैं - वे सूचियों के बीच कुछ सापेक्ष क्रम मान लेते हैं। एक अनियंत्रित समाधान दो सेटों को फैलाना होगा।
पाइलैंग

4

यह एक और उपाय है:

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

यदि आप में भाग लेते हैं, तो आपको TypeError: unhashable type: 'list'सूचियों को चालू करने या टुपल्स में सेट करने की आवश्यकता होती है, जैसे

set(map(tuple, list_of_lists1)).symmetric_difference(set(map(tuple, list_of_lists2)))

यह भी देखें कि अजगर में सूचियों / सेट की सूची की तुलना कैसे करें?


4

मान लीजिए कि हमारी दो सूचियाँ हैं

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

हम उपरोक्त दो सूचियों से देख सकते हैं कि आइटम 1, 3, 5 सूची 2 में मौजूद हैं और आइटम 7, 9 नहीं हैं। दूसरी ओर, आइटम 1, 3, 5 सूची 1 में मौजूद हैं और आइटम 2, 4 नहीं हैं।

आइटम 7, 9 और 2, 4 वाली नई सूची वापस करने के लिए सबसे अच्छा समाधान क्या है?

उपरोक्त सभी उत्तर समाधान ढूंढते हैं, अब सबसे इष्टतम क्या है?

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

बनाम

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

समय का उपयोग करके हम परिणाम देख सकते हैं

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

रिटर्न

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

Process finished with exit code 0


3

यदि आप एक बदलाव की तरह कुछ और चाहते हैं ... काउंटर का उपयोग कर सकते हैं

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

हम सूचियों के प्रतिच्छेदन ऋण संघ की गणना कर सकते हैं:

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

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

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

2

इसे एक लाइन से हल किया जा सकता है। सवाल दो सूचियों (temp1 और temp2) को दिया गया है, तीसरी सूची (temp3) में अपना अंतर लौटाते हैं।

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

1

यहां दो सूचियों (जो भी सामग्री हैं) को अलग करने का एक सरल तरीका है, आप नीचे दिखाए अनुसार परिणाम प्राप्त कर सकते हैं:

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

आशा है कि यह मददगार होगा।


0

मैं सेट और फिर "अंतर ()" फ़ंक्शन का उपयोग करके कनवर्ट करना पसंद करता हूं। पूर्ण कोड है:

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

आउटपुट:

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

यदि आप बड़े डेटा के साथ काम करते हैं, तो भविष्य में इसे हटाना आसान है, और अगर आप डुप्लिकेट की आवश्यकता नहीं है, तो इसे डुप्लिकेट में बदल देंगे। आशा है ये मदद करेगा ;-)


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

3
उत्तर प्रदान करने के अलावा, क्या आप इस बात के लिए स्पष्टीकरण दे सकते हैं कि यह इस विशेष मुद्दे पर कैसे काम करता है / लागू होता है? उत्तर और समाधान महान हैं, लेकिन विस्तृत गाइड और स्पष्टीकरण असीम रूप से बेहतर हैं।
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)))

उदाहरण के लिए यदि list1 = [10, 15, 20, 25, 30, 35, 40]और list2 = [25, 40, 35]फिर लौटी सूची होगीoutput = [10, 20, 30, 15]


अंतर ऑपरेशन के लिए आप ऐसा नहीं कर सकते। पूर्णांक के मामले में भी, यदि आप 'a - b' करने के लिए कोई फंक्शन बताते हैं, तो 'b' को 'a' से ही घटाया जाना चाहिए, भले ही 'b' 'a' से बड़ा हो या अन्यथा। सूची और सेट के मामले में भी ऐसा ही है। ए - बी और बी - ए दोनों ए और बी की लंबाई के बावजूद वैध संचालन हो सकते हैं, आपको केवल ए - बी प्रदर्शन करने के लिए ए से बी की सामग्री को बाहर करने की आवश्यकता है।
अबू तल्हा दानिश
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.