दो शब्दकोशों की तुलना करें और जांचें कि कितने (कुंजी, मूल्य) जोड़े समान हैं


246

मेरे पास दो शब्दकोश हैं, लेकिन सरलीकरण के लिए, मैं इन दोनों को ले जाऊंगा:

>>> x = dict(a=1, b=2)
>>> y = dict(a=2, b=2)

अब, मैं तुलना करना चाहता हूं कि क्या प्रत्येक key, valueजोड़ी में xसमान मूल्य है y। इसलिए मैंने यह लिखा:

>>> for x_values, y_values in zip(x.iteritems(), y.iteritems()):
        if x_values == y_values:
            print 'Ok', x_values, y_values
        else:
            print 'Not', x_values, y_values

और यह तब से काम करता है जब tupleलौटा है और फिर समानता की तुलना में है।

मेरे सवाल:

क्या ये सही है? क्या ऐसा करने का एक बेहतर तरीका है? गति में बेहतर नहीं, मैं कोड लालित्य के बारे में बात कर रहा हूं।

अद्यतन: मैं यह उल्लेख करना भूल गया कि मुझे यह जाँचना है कि कितने key, valueजोड़े बराबर हैं।



x == y सत्य होना चाहिए। आरईपीएल में कोई भी जल्दी जांच कर सकता है। कृपया देखें: docs.python.org/2/library/stdtypes.html#mapping-types-dict
विक्रांत

जवाबों:


179

यदि आप जानना चाहते हैं कि दोनों शब्दकोशों में कितने मूल्य मेल खाते हैं, तो आपको कहना चाहिए कि :)

शायद कुछ इस तरह:

shared_items = {k: x[k] for k in x if k in y and x[k] == y[k]}
print len(shared_items)

1
यदि समान कुंजी के लिए सूची तत्व है तो समान त्रुटि। मुझे लगता है कि cmp इसे करने का बेहतर तरीका है जब तक कि मुझे कुछ याद न हो।
उत्पाती

@ म्यूटेंट एक अलग मुद्दा है। आप listपहली बार एक कुंजी के साथ एक शब्दकोश नहीं बना सकते । x = {[1,2]: 2}असफल हो जायेगी। प्रश्न पहले से ही मान्य है dicts
अन्नानफे

@ यान: गलत, सवाल सामान्य है। उदाहरण के सवाल वर्णन में पहले से ही "वैध dicts" है। यदि मैं एक ही शीर्षक के साथ एक नया प्रश्न पोस्ट करता हूं, लेकिन एक अलग "अमान्य" तानाशाही के साथ, कोई इसे डुप्लिकेट के रूप में चिह्नित करेगा। Downvoting।
रिबमार

6
@ribamar का सवाल है "दो शब्दकोशों की तुलना [...]"। listकुंजी के साथ ऊपर 'अमान्य तानाशाह' मान्य अजगर कोड नहीं है - तानाशाही चाबियाँ अपरिवर्तनीय होनी चाहिए। इसलिए आप शब्दकोशों की तुलना नहीं कर रहे हैं। यदि आप कोशिश करते हैं और शब्दकोश कुंजी के रूप में एक सूची का उपयोग करते हैं तो आपका कोड नहीं चलेगा। आपके पास कोई ऑब्जेक्ट नहीं है जिसके लिए तुलना करें। यह टाइपिंग की तरह है, x = dict(23\;dfg&^*$^%$^$%^)फिर शिकायत करना कि कैसे शब्दकोश के साथ तुलना नहीं होती है। बेशक यह काम नहीं करेगा। दूसरी ओर टिम की टिप्पणी परस्पर के बारे में है values, इसलिए मैंने कहा कि ये अलग-अलग मुद्दे हैं।
अन्नपूर्णे

1
@ मायके - setको धोने योग्य होने के लिए मूल्यों की आवश्यकता होती है और धोने योग्य होने के dictलिए कुंजी की आवश्यकता होती है। set(x.keys())हमेशा काम करेगा क्योंकि चाबियों को धोने योग्य होने की आवश्यकता होती है, लेकिन उन set(x.values())मूल्यों पर विफल होंगे जो धोने योग्य नहीं हैं।
टिम टिसडल

173

आप जो करना चाहते हैं वह बस है x==y

आप जो करते हैं वह एक अच्छा विचार नहीं है, क्योंकि किसी शब्दकोश में आइटमों के लिए कोई आदेश नहीं है। आप (समान शब्दकोष, अलग-अलग आदेश) के [('a',1),('b',1)]साथ तुलना कर सकते हैं [('b',1), ('a',1)]

उदाहरण के लिए, इसे देखें:

>>> x = dict(a=2, b=2,c=3, d=4)
>>> x
{'a': 2, 'c': 3, 'b': 2, 'd': 4}
>>> y = dict(b=2,c=3, d=4)
>>> y
{'c': 3, 'b': 2, 'd': 4}
>>> zip(x.iteritems(), y.iteritems())
[(('a', 2), ('c', 3)), (('c', 3), ('b', 2)), (('b', 2), ('d', 4))]

अंतर केवल एक आइटम का है, लेकिन आपका एल्गोरिदम यह देखेगा कि सभी आइटम अलग-अलग हैं


@ THC4k, उल्लेख न करने के लिए क्षमा करें। लेकिन मुझे यह जांचना होगा कि दोनों शब्दकोशों में कितने मूल्य मेल खाते हैं।
user225312

ठीक है, इसलिए मेरे अपडेट के आधार पर, क्या मेरा तरीका अभी भी गलत है?
user225312

@ एएए: मैंने जोड़ा कि जब आप गिनती करना चाहते हैं तो आपका काम क्यों नहीं होता है।
जोहान रिट्जेल

मैं देखता हूं, लेकिन मेरे मामले में दोनों शब्दकोश समान लंबाई के हैं। और वे हमेशा रहेंगे, क्योंकि कार्यक्रम इसी तरह काम करता है।
user225312

5
पाइथन 3.6 के रूप में, तानाशाह आउट-ऑफ-द-बॉक्स है।
फिल

163
def dict_compare(d1, d2):
    d1_keys = set(d1.keys())
    d2_keys = set(d2.keys())
    shared_keys = d1_keys.intersection(d2_keys)
    added = d1_keys - d2_keys
    removed = d2_keys - d1_keys
    modified = {o : (d1[o], d2[o]) for o in shared_keys if d1[o] != d2[o]}
    same = set(o for o in shared_keys if d1[o] == d2[o])
    return added, removed, modified, same

x = dict(a=1, b=2)
y = dict(a=2, b=2)
added, removed, modified, same = dict_compare(x, y)

7
यह वास्तव में तानाशाह में परिवर्तनशील मूल्यों को संभालता है!
टिम टिस्डाल

1
जब मैं इसे चलाता हूं, तब भी मुझे एक परिवर्तनशील मूल्यों के साथ काम करते हुए एक त्रुटि मिलती है: ValueError: एक DataFrame का सत्य मान अस्पष्ट है। A.empty, a.bool (), a.item (), a.any () या a.all () का उपयोग करें।
अफलातून

2
@Afflatus - DataFrameडिजाइन के अनुसार सत्य तुलना की अनुमति नहीं देते हैं (जब तक कि इसकी लंबाई 1 नहीं है) क्योंकि वे विरासत में मिले हैं numpy.ndarray। -credit को stackoverflow.com/a/33307396/994076
डैनियल मायर्स

यह एक पूर्ण रत्न है।
pfabri

125

dic1 == dic2

से अजगर डॉक्स :

उदाहरण के लिए, निम्नलिखित उदाहरण सभी के लिए एक शब्दकोष के बराबर हैं {"one": 1, "two": 2, "three": 3}:

>>> a = dict(one=1, two=2, three=3)
>>> b = {'one': 1, 'two': 2, 'three': 3}
>>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
>>> d = dict([('two', 2), ('one', 1), ('three', 3)])
>>> e = dict({'three': 3, 'one': 1, 'two': 2})
>>> a == b == c == d == e
True

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

दोनों के लिए मान्य py2और py3


3
मैं @ ErkinAlpGüney से सहमत नहीं हूं। क्या आप कोई प्रमाण दे सकते हैं?
क्यूई लुओ

4
मैं @ ErkinAlpGüney से असहमत हूं। आधिकारिक दस्तावेज से पता चलता है कि == वास्तव में शब्दकोशों द्वारा मूल्य की तुलना करता है, पते से नहीं। docs.python.org/2/library/stdtypes.html#mapping-types-dict
मैथ्यू

3
पाइथन 2.7.13 के लिए काम करता है
जेसुइस्म

4
@ankostis:OrderedDict != dict
CONvid19

3
क्या आप कृपया एक इनपुट प्रदान कर सकते हैं जहाँ यह सच नहीं है?
CONvid19

55

मैं अजगर के लिए नया हूं लेकिन मैंने @mouad के साथ कुछ ऐसा ही किया

unmatched_item = set(dict_1.items()) ^ set(dict_2.items())
len(unmatched_item) # should be 0

एक्सओआर ऑपरेटर ( ^) को हुक के सभी तत्वों को समाप्त करना चाहिए जब वे दोनों डिट्स में समान हों।


28
दुर्भाग्यवश यह काम नहीं करता है यदि हुकुम में मान परस्पर हैं (यानी धोने योग्य नहीं)। (पूर्व {'a':{'b':1}}देता है TypeError: unhashable type: 'dict')
टिम टिसडल

54

चूंकि यह किसी का उल्लेख नहीं है deepdiff, इसलिए मैं इसे पूर्णता के लिए यहां जोड़ दूंगा। मैं इसे (नेस्टेड) ​​वस्तुओं के सामान्य रूप से भिन्न होने के लिए बहुत सुविधाजनक मानता हूं:

स्थापना

pip install deepdiff

नमूना कोड

import deepdiff
import json

dict_1 = {
    "a": 1,
    "nested": {
        "b": 1,
    }
}

dict_2 = {
    "a": 2,
    "nested": {
        "b": 2,
    }
}

diff = deepdiff.DeepDiff(dict_1, dict_2)
print(json.dumps(diff, indent=4))

उत्पादन

{
    "values_changed": {
        "root['a']": {
            "new_value": 2,
            "old_value": 1
        },
        "root['nested']['b']": {
            "new_value": 2,
            "old_value": 1
        }
    }
}

निरीक्षण के लिए सुंदर-मुद्रण परिणाम के बारे में ध्यान दें: उपरोक्त कोड काम करता है यदि दोनों dicts में समान विशेषता कुंजियाँ होती हैं (उदाहरण में अलग-अलग विशेषता मान)। हालाँकि, यदि कोई "extra"विशेषता मौजूद है, तो dicts में से एक, के json.dumps()साथ विफल रहता है

TypeError: Object of type PrettyOrderedSet is not JSON serializable

समाधान: उपयोग diff.to_json()और json.loads()/ json.dumps()से प्रिंट करने के लिए:

import deepdiff
import json

dict_1 = {
    "a": 1,
    "nested": {
        "b": 1,
    },
    "extra": 3
}

dict_2 = {
    "a": 2,
    "nested": {
        "b": 2,
    }
}

diff = deepdiff.DeepDiff(dict_1, dict_2)
print(json.dumps(json.loads(diff.to_json()), indent=4))  

आउटपुट:

{
    "dictionary_item_removed": [
        "root['extra']"
    ],
    "values_changed": {
        "root['a']": {
            "new_value": 2,
            "old_value": 1
        },
        "root['nested']['b']": {
            "new_value": 2,
            "old_value": 1
        }
    }
}

वैकल्पिक: pprintएक अलग स्वरूपण में उपयोग , परिणाम:

import pprint

# same code as above

pprint.pprint(diff, indent=4)

आउटपुट:

{   'dictionary_item_removed': [root['extra']],
    'values_changed': {   "root['a']": {   'new_value': 2,
                                           'old_value': 1},
                          "root['nested']['b']": {   'new_value': 2,
                                                     'old_value': 1}}}

2
दिलचस्प। इसका उत्तर देने के लिए धन्यवाद। मेरे लिए कम से कम उपयोगी है। इस उत्तर को और अधिक बढ़ाने की जरूरत है।
अर्चित कपूर

46

महज प्रयोग करें:

assert cmp(dict1, dict2) == 0

6
ऐसा लगता है कि कार्य केवल यह जांचने के लिए नहीं है कि दोनों की सामग्री समान है, बल्कि मतभेदों की एक रिपोर्ट भी देनी है
डिएगो टेरसेरो

29
मेरा मानना ​​है कि यह समान हैdict1 == dict2
ट्रे हंटर

10
Python3.5 का उपयोग करने वाले किसी के लिए, cmpनिर्मित में हटा दिया गया है (और इसे पहले हटाए जाने के रूप में माना जाना चाहिए । एक विकल्प वे प्रस्तावित करते हैं: (a > b) - (a < b) == cmp(a, b)एक कार्यात्मक समकक्ष (या बेहतर __eq__और __hash__) के लिए
nerdwaller

3
@nerdwaller - dicts orderable प्रकार नहीं हैं, इसलिए dict_a> dict_b एक उठाएंगे TypeError:unorderable types: dict() < dict()
Stefano

2
@Stefano: अच्छा फोन, मेरी टिप्पणी अजगर में सामान्य तुलना के लिए अधिक थी (मैं वास्तविक उत्तर, मेरी गलती पर ध्यान नहीं दे रहा था)।
nerdwaller

9

यदि आप मानते हैं कि दोनों शब्दकोशों में केवल सरल मूल्य हैं, तो @mouad का उत्तर अच्छा है। हालाँकि, यदि आपके पास ऐसे शब्दकोष हैं, जिनमें शब्दकोष हैं तो आपको अपवाद मिलेगा क्योंकि शब्दकोश ह्रास योग्य नहीं हैं।

मेरे सिर के ऊपर से, कुछ इस तरह से काम कर सकते हैं:

def compare_dictionaries(dict1, dict2):
     if dict1 is None or dict2 is None:
        print('Nones')
        return False

     if (not isinstance(dict1, dict)) or (not isinstance(dict2, dict)):
        print('Not dict')
        return False

     shared_keys = set(dict1.keys()) & set(dict2.keys())

     if not ( len(shared_keys) == len(dict1.keys()) and len(shared_keys) == len(dict2.keys())):
        print('Not all keys are shared')
        return False


     dicts_are_equal = True
     for key in dict1.keys():
         if isinstance(dict1[key], dict) or isinstance(dict2[key], dict):
             dicts_are_equal = dicts_are_equal and compare_dictionaries(dict1[key], dict2[key])
         else:
             dicts_are_equal = dicts_are_equal and all(atleast_1d(dict1[key] == dict2[key]))

     return dicts_are_equal

यदि आप not isinstance(dict1, dict)इसके बजाय का उपयोग करते हैं type(dict1) is not dict, तो यह अन्य वर्गों पर काम करेगा dict. Also, instead of (तानाशाही [कुंजी] == तानाशाही [कुंजी]) पर आधारित , you can do सभी (atleast_1d (तानाशाही [कुंजी] == तानाशाही [कुंजी])) `कम से कम सरणियों को संभालने के लिए।
EL_DON

+1, लेकिन for loopजैसे ही आप अपने dicts_are_equalझूठे को तोड़ सकते हैं । आगे भी जारी रखने की आवश्यकता नहीं है।
pfabri

6

फिर भी, ओपी के अंतिम नोट तक एक और संभावना, JSON के रूप में डंप किए गए डाइट के हैश ( SHAया MD) की तुलना करना है । जिस तरह से हैश का निर्माण किया जाता है, यदि वे समान हैं, तो स्रोत के तार भी समान हैं। यह बहुत तेज और गणितीय ध्वनि है।

import json
import hashlib

def hash_dict(d):
    return hashlib.sha1(json.dumps(d, sort_keys=True)).hexdigest()

x = dict(a=1, b=2)
y = dict(a=2, b=2)
z = dict(a=1, b=2)

print(hash_dict(x) == hash_dict(y))
print(hash_dict(x) == hash_dict(z))

2
यह पूरी तरह से गलत है, केवल डेटा को जसन में पार्स करना वास्तव में धीमा है। फिर हैशिंग ने जो विशाल सिरा बनाया है वह और भी खराब है। आपको ऐसा कभी नहीं करना चाहिए
ब्रूनो

7
@ ब्रूनो: ओपी को उद्धृत करते हुए: "गति में बेहतर नहीं, मैं कोड लालित्य के बारे में बात कर रहा हूं"
WoJ

2
यह बिल्कुल भी सुरुचिपूर्ण नहीं है, यह असुरक्षित महसूस करता है और यह वास्तव में सरल समस्या के लिए अत्यधिक जटिल है
ब्रूनो

7
@ ब्रूनो: लालित्य व्यक्तिपरक है। मैं समझ सकता हूं कि आपको यह पसंद नहीं है (और शायद डाउनवोट किया गया है)। यह "गलत" के समान नहीं है।
WoJ

4
यह एक बेहतरीन जवाब है। json.dumps(d, sort_keys=True)आपको विहित JSON दे देगा ताकि आप निश्चित हो सकें कि दोनों तानाशाह समान हैं। यह भी निर्भर करता है कि आप क्या हासिल करने की कोशिश कर रहे हैं। जैसे ही मान JSON सेरिज़ेलेबल नहीं है, यह विफल हो जाएगा। इस प्रकार जो कहते हैं कि यह अक्षम है, उज्सन परियोजना पर एक नजर है।
नटिम

6

समारोह ठीक IMO, स्पष्ट और सहज है। लेकिन सिर्फ आपको (एक और) जवाब देने के लिए, यहाँ मेरा जाना है:

def compare_dict(dict1, dict2):
    for x1 in dict1.keys():
        z = dict1.get(x1) == dict2.get(x1)
        if not z:
            print('key', x1)
            print('value A', dict1.get(x1), '\nvalue B', dict2.get(x1))
            print('-----\n')

आपके लिए या किसी और के लिए उपयोगी हो सकता है।

संपादित करें:

मैंने ऊपर वाले का एक पुनरावर्ती संस्करण बनाया है .. जो अन्य उत्तरों में नहीं देखा है

def compare_dict(a, b):
    # Compared two dictionaries..
    # Posts things that are not equal..
    res_compare = []
    for k in set(list(a.keys()) + list(b.keys())):
        if isinstance(a[k], dict):
            z0 = compare_dict(a[k], b[k])
        else:
            z0 = a[k] == b[k]

        z0_bool = np.all(z0)
        res_compare.append(z0_bool)
        if not z0_bool:
            print(k, a[k], b[k])
    return np.all(res_compare)

2
चलो इसे सुधारें ताकि यह दोनों तरीके से काम करे। पंक्ति 2: "एक्स 1 के लिए सेट में (तानाशाही। हाथी ())। संघ (तानाशाही 2) ()):"
nkadwa

धन्यवाद @nkadwa, अब यह करता है
zwep

5

यह जांचने के लिए कि क्या दो डाईट कुंजियों और मानों में बराबर हैं:

def dicts_equal(d1,d2):
    """ return True if all keys and values are the same """
    return all(k in d2 and d1[k] == d2[k]
               for k in d1) \
        and all(k in d1 and d1[k] == d2[k]
               for k in d2)

यदि आप उन मूल्यों को वापस करना चाहते हैं जो अलग-अलग हैं, तो इसे अलग तरीके से लिखें:

def dict1_minus_d2(d1, d2):
    """ return the subset of d1 where the keys don't exist in d2 or
        the values in d2 are different, as a dict """
    return {k,v for k,v in d1.items() if k in d2 and v == d2[k]}

आपको इसे दो बार कॉल करना होगा

dict1_minus_d2(d1,d2).extend(dict1_minus_d2(d2,d1))

3

कोड

def equal(a, b):
    type_a = type(a)
    type_b = type(b)
    
    if type_a != type_b:
        return False
    
    if isinstance(a, dict):
        if len(a) != len(b):
            return False
        for key in a:
            if key not in b:
                return False
            if not equal(a[key], b[key]):
                return False
        return True

    elif isinstance(a, list):
        if len(a) != len(b):
            return False
        while len(a):
            x = a.pop()
            index = indexof(x, b)
            if index == -1:
                return False
            del b[index]
        return True
        
    else:
        return a == b

def indexof(x, a):
    for i in range(len(a)):
        if equal(x, a[i]):
            return i
    return -1

परीक्षा

>>> a = {
    'number': 1,
    'list': ['one', 'two']
}
>>> b = {
    'list': ['two', 'one'],
    'number': 1
}
>>> equal(a, b)
True

3

== के साथ एक सरल तुलना आजकल पर्याप्त होनी चाहिए (अजगर 3.8)। यहां तक ​​कि जब आप एक ही आदेश (पिछले उदाहरण) में एक ही dicts की तुलना करते हैं। सबसे अच्छी बात यह है कि इसे पूरा करने के लिए आपको किसी तीसरे पक्ष के पैकेज की आवश्यकता नहीं है।

a = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}
b = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}

c = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}
d = {'one': 'dog', 'two': 'cat', 'three': 'mouse', 'four': 'fish'}

e = {'one': 'cat', 'two': 'dog', 'three': 'mouse'}
f = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}

g = {'two': 'cat', 'one': 'dog', 'three': 'mouse'}
h = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}


print(a == b) # True
print(c == d) # False
print(e == f) # False
print(g == h) # True

2

मेरी प्रतिक्रिया में देर होना कभी भी बेहतर नहीं है!

तुलना की तुलना में Not_Equal अधिक कुशल है। जैसे कि दो डिक्टेट समान नहीं हैं यदि एक तानाशाह में कोई महत्वपूर्ण मूल्य दूसरे तानाशाह में नहीं पाया जाता है। नीचे दिए गए कोड पर ध्यान दिया जाता है कि आप डिफ़ॉल्ट डिफॉल्ट की तुलना कर रहे हैं और इस प्रकार गेटिटेम [] के बजाय प्राप्त करें ।

पुनर्प्राप्त की जा रही कॉल के बराबर डिफ़ॉल्ट के रूप में एक तरह के यादृच्छिक मूल्य का उपयोग करना - बस अगर मामले में डक्ट्स का एक तानाशाही में कोई मूल्य नहीं है और वह कुंजी दूसरे में मौजूद नहीं है। यह भी प्राप्त करें! = हालत दक्षता के लिए नहीं हालत से पहले जाँच की है क्योंकि आप एक ही समय में दोनों पक्षों से चाबियाँ और मूल्यों पर जाँच कर रहे हैं।

def Dicts_Not_Equal(first,second):
    """ return True if both do not have same length or if any keys and values are not the same """
    if len(first) == len(second): 
        for k in first:
            if first.get(k) != second.get(k,k) or k not in second: return (True)
        for k in second:         
            if first.get(k,k) != second.get(k) or k not in first: return (True)
        return (False)   
    return (True)

2

मैं इस समाधान का उपयोग कर रहा हूं जो कि पायथन 3 में मेरे लिए पूरी तरह से काम करता है


import logging
log = logging.getLogger(__name__)

...

    def deep_compare(self,left, right, level=0):
        if type(left) != type(right):
            log.info("Exit 1 - Different types")
            return False

        elif type(left) is dict:
            # Dict comparison
            for key in left:
                if key not in right:
                    log.info("Exit 2 - missing {} in right".format(key))
                    return False
                else:
                    if not deep_compare(left[str(key)], right[str(key)], level +1 ):
                        log.info("Exit 3 - different children")
                        return False
            return True
        elif type(left) is list:
            # List comparison
            for key in left:
                if key not in right:
                    log.info("Exit 4 - missing {} in right".format(key))
                    return False
                else:
                    if not deep_compare(left[left.index(key)], right[right.index(key)], level +1 ):
                        log.info("Exit 5 - different children")
                        return False
            return True
        else:
            # Other comparison
            return left == right

        return False

यह तानाशाह, सूची और किसी भी अन्य प्रकार की तुलना करता है जो "==" ऑपरेटर को खुद से लागू करता है। यदि आपको किसी और चीज़ की तुलना करने की आवश्यकता है, तो आपको "अगर पेड़" में एक नई शाखा जोड़ने की आवश्यकता है।

उम्मीद है की वो मदद करदे।



1
>>> hash_1
{'a': 'foo', 'b': 'bar'}
>>> hash_2
{'a': 'foo', 'b': 'bar'}
>>> set_1 = set (hash_1.iteritems())
>>> set_1
set([('a', 'foo'), ('b', 'bar')])
>>> set_2 = set (hash_2.iteritems())
>>> set_2
set([('a', 'foo'), ('b', 'bar')])
>>> len (set_1.difference(set_2))
0
>>> if (len(set_1.difference(set_2)) | len(set_2.difference(set_1))) == False:
...    print "The two hashes match."
...
The two hashes match.
>>> hash_2['c'] = 'baz'
>>> hash_2
{'a': 'foo', 'c': 'baz', 'b': 'bar'}
>>> if (len(set_1.difference(set_2)) | len(set_2.difference(set_1))) == False:
...     print "The two hashes match."
...
>>>
>>> hash_2.pop('c')
'baz'

यहाँ एक और विकल्प है:

>>> id(hash_1)
140640738806240
>>> id(hash_2)
140640738994848

तो जैसा कि आप देखते हैं कि दोनों आईडी अलग-अलग हैं। लेकिन अमीर तुलना ऑपरेटरों को लगता है कि यह चाल है:

>>> hash_1 == hash_2
True
>>>
>>> hash_2
{'a': 'foo', 'b': 'bar'}
>>> set_2 = set (hash_2.iteritems())
>>> if (len(set_1.difference(set_2)) | len(set_2.difference(set_1))) == False:
...     print "The two hashes match."
...
The two hashes match.
>>>

1

PyUnit में एक ऐसा तरीका है जो शब्दकोशों की खूबसूरती से तुलना करता है। मैंने निम्नलिखित दो शब्दकोशों का उपयोग करके इसका परीक्षण किया, और यह वही करता है जो आप खोज रहे हैं।

d1 = {1: "value1",
      2: [{"subKey1":"subValue1",
           "subKey2":"subValue2"}]}
d2 = {1: "value1",
      2: [{"subKey2":"subValue2",
           "subKey1": "subValue1"}]
      }


def assertDictEqual(self, d1, d2, msg=None):
        self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
        self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')

        if d1 != d2:
            standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
            diff = ('\n' + '\n'.join(difflib.ndiff(
                           pprint.pformat(d1).splitlines(),
                           pprint.pformat(d2).splitlines())))
            standardMsg = self._truncateMessage(standardMsg, diff)
            self.fail(self._formatMessage(msg, standardMsg))

मैं unittestआपके उत्पादन कोड में आयात करने की अनुशंसा नहीं कर रहा हूँ । मेरा विचार है PyUnit में स्रोत उत्पादन में चलाने के लिए फिर से उपकरण हो सकता है। यह pprintशब्दकोशों का "सुंदर प्रिंट" का उपयोग करता है । "कोड तैयार" होने के लिए इस कोड को अनुकूलित करने के लिए बहुत आसान लगता है।


1

शब्दकोश दृश्य ऑब्जेक्ट देखें: https://docs.python.org/2/library/stdtypes.html#dict

इस तरह आप dictView1 से dictView2 को घटा सकते हैं और यह कुंजी / मान जोड़े के एक सेट को लौटाएगा जो तानाशाह के दृश्य में अलग हैं:

original = {'one':1,'two':2,'ACTION':'ADD'}
originalView=original.viewitems()
updatedDict = {'one':1,'two':2,'ACTION':'REPLACE'}
updatedDictView=updatedDict.viewitems()
delta=original | updatedDict
print delta
>>set([('ACTION', 'REPLACE')])

आप अंतरंग, संघ, अंतर (ऊपर दिखाया गया है), इन शब्दकोश दृश्य वस्तुओं को सममित अंतर कर सकते हैं।
बेहतर? और तेज? - निश्चित नहीं है, लेकिन मानक पुस्तकालय का हिस्सा है - जो इसे पोर्टेबिलिटी के लिए एक बड़ा प्लस बनाता है


1

नीचे दिए गए कोड से आपको अजगर में तानाशाह की सूची की तुलना करने में मदद मिलेगी

def compate_generic_types(object1, object2):
    if isinstance(object1, str) and isinstance(object2, str):
        return object1 == object2
    elif isinstance(object1, unicode) and isinstance(object2, unicode):
        return object1 == object2
    elif isinstance(object1, bool) and isinstance(object2, bool):
        return object1 == object2
    elif isinstance(object1, int) and isinstance(object2, int):
        return object1 == object2
    elif isinstance(object1, float) and isinstance(object2, float):
        return object1 == object2
    elif isinstance(object1, float) and isinstance(object2, int):
        return object1 == float(object2)
    elif isinstance(object1, int) and isinstance(object2, float):
        return float(object1) == object2

    return True

def deep_list_compare(object1, object2):
    retval = True
    count = len(object1)
    object1 = sorted(object1)
    object2 = sorted(object2)
    for x in range(count):
        if isinstance(object1[x], dict) and isinstance(object2[x], dict):
            retval = deep_dict_compare(object1[x], object2[x])
            if retval is False:
                print "Unable to match [{0}] element in list".format(x)
                return False
        elif isinstance(object1[x], list) and isinstance(object2[x], list):
            retval = deep_list_compare(object1[x], object2[x])
            if retval is False:
                print "Unable to match [{0}] element in list".format(x)
                return False
        else:
            retval = compate_generic_types(object1[x], object2[x])
            if retval is False:
                print "Unable to match [{0}] element in list".format(x)
                return False

    return retval

def deep_dict_compare(object1, object2):
    retval = True

    if len(object1) != len(object2):
        return False

    for k in object1.iterkeys():
        obj1 = object1[k]
        obj2 = object2[k]
        if isinstance(obj1, list) and isinstance(obj2, list):
            retval = deep_list_compare(obj1, obj2)
            if retval is False:
                print "Unable to match [{0}]".format(k)
                return False

        elif isinstance(obj1, dict) and isinstance(obj2, dict):
            retval = deep_dict_compare(obj1, obj2)
            if retval is False:
                print "Unable to match [{0}]".format(k)
                return False
        else:
            retval = compate_generic_types(obj1, obj2)
            if retval is False:
                print "Unable to match [{0}]".format(k)
                return False

    return retval

3
ढेर अतिप्रवाह में आपका स्वागत है! हालांकि यह कोड स्निपेट प्रश्न को हल कर सकता है, जिसमें स्पष्टीकरण सहित वास्तव में आपकी पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और उन लोगों को आपके कोड सुझाव के कारणों का पता नहीं चल सकता है। कृपया व्याख्यात्मक टिप्पणियों के साथ अपने कोड को भीड़ने की कोशिश न करें, इससे कोड और स्पष्टीकरण दोनों की पठनीयता कम हो जाती है!
फाइलर

1
>>> x = {'a':1,'b':2,'c':3}
>>> x
{'a': 1, 'b': 2, 'c': 3}

>>> y = {'a':2,'b':4,'c':3}
>>> y
{'a': 2, 'b': 4, 'c': 3}

METHOD 1:

>>> common_item = x.items()&y.items() #using union,x.item() 
>>> common_item
{('c', 3)}

METHOD 2:

 >>> for i in x.items():
        if i in y.items():
           print('true')
        else:
           print('false')


false
false
true

0

पायथन 3.6 में, इसे इस प्रकार किया जा सकता है: -

if (len(dict_1)==len(dict_2): 
  for i in dict_1.items():
        ret=bool(i in dict_2.items())

रिट वेरिएबल सही होगा यदि तानाशाही के सभी आइटम_1 में मौजूद हैं


0

यहाँ मेरा जवाब है, एक पुनरावर्ती तरीके का उपयोग करें:

def dict_equals(da, db):
    if not isinstance(da, dict) or not isinstance(db, dict):
        return False
    if len(da) != len(db):
        return False
    for da_key in da:
        if da_key not in db:
            return False
        if not isinstance(db[da_key], type(da[da_key])):
            return False
        if isinstance(da[da_key], dict):
            res = dict_equals(da[da_key], db[da_key])
            if res is False:
                return False
        elif da[da_key] != db[da_key]:
            return False
    return True

a = {1:{2:3, 'name': 'cc', "dd": {3:4, 21:"nm"}}}
b = {1:{2:3, 'name': 'cc', "dd": {3:4, 21:"nm"}}}
print dict_equals(a, b)

उम्मीद है की वो मदद करदे!


0

केवल एक शब्दकोश के माध्यम से पुनरावृत्ति क्यों न करें और प्रक्रिया में दूसरे की जांच करें (दोनों शब्दकोशों में एक ही कुंजी है)?

x = dict(a=1, b=2)
y = dict(a=2, b=2)

for key, val in x.items():
    if val == y[key]:
        print ('Ok', val, y[key])
    else:
        print ('Not', val, y[key])

आउटपुट:

Not 1 2
Ok 2 2

0

दो शब्दकोशों की गहरी तुलना करने के लिए सबसे आसान तरीका (और उस पर अधिक मजबूत में से एक) उन्हें JSON प्रारूप में क्रमबद्ध करना, कुंजियों को क्रमबद्ध करना और स्ट्रिंग परिणामों की तुलना करना है:

import json
if json.dumps(x, sort_keys=True) == json.dumps(y, sort_keys=True):
   ... Do something ...

-7
import json

if json.dumps(dict1) == json.dumps(dict2):
    print("Equal")

1
यह वह नहीं कर सकता है जो वास्तव में अनुरोध किया गया था, और json std lib में खींचता है, लेकिन यह काम करता है (जैसा json.dumpsकि डिफ़ॉल्ट सेटिंग्स के साथ निर्धारक है)।
डैनियल फैरेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.