দুটি অভিধানের তুলনা এবং কতগুলি (কী, মান) জোড়া সমান তা পরীক্ষা করা


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জোড়া সমান তা পরীক্ষা করতে হবে।


21
x == yঅনুযায়ী সত্য হওয়া উচিত stackoverflow.com/a/5635309/186202
Natim

x == y সত্য হওয়া উচিত। কেউ দ্রুত আরএপিএলে চেক করতে পারেন। দয়া করে রেফারেন্স
বিক্রান্ত

উত্তর:


179

আপনি যদি উভয় অভিধানের মধ্যে কতগুলি মান মেলে তা জানতে চান, আপনার এটি বলা উচিত ছিল :)

এরকম কিছু হতে পারে:

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

1
ডিক কীটির জন্য তালিকার উপাদান উপস্থিত থাকলে একই ত্রুটি। আমি মনে করি সিএমপি এটি করার আরও ভাল উপায় যদি না আমি কিছু মিস না করি।
মিউট্যান্ট

@ মিউট্যান্ট এটি একটি আলাদা সমস্যা। আপনি listপ্রথমে কী দিয়ে একটি অভিধান তৈরি করতে পারবেন না । x = {[1,2]: 2}অকৃতকার্য হবে. প্রশ্ন ইতিমধ্যে বৈধ আছে dicts
আনানফায়

@ নানান: ভুল, প্রশ্নটি জেনেরিক। উদাহরণস্বরূপ প্রশ্ন বর্ণনাতে ইতিমধ্যে "বৈধ dicts" আছে। যদি আমি একই শিরোনাম সহ একটি নতুন প্রশ্ন পোস্ট করি তবে ভিন্ন "অবৈধ" ডিক দিয়ে, কেউ এটিকে নকল হিসাবে চিহ্নিত করবে। Downvoting।
ribamar

6
@ রাইবার প্রশ্নটি হচ্ছে "দুটি অভিধানের তুলনা [...]"। 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, উল্লেখ না করার জন্য দুঃখিত। তবে আমাকে দুটি অভিধানে কতগুলি মান মেলে তা পরীক্ষা করে দেখতে হবে।
ব্যবহারকারী225312

ঠিক আছে, তাই আমার আপডেটের ভিত্তিতে, আমার কাজ করার পদ্ধতিটি কি এখনও ভুল?
ব্যবহারকারী 225312

@ এএ: আমি যুক্ত করেছি যখন আপনি গণনা করতে চান তখন কেন আপনার কাজ হয় না।
জোচেন রিটজেল

আমি দেখতে পাচ্ছি, তবে আমার ক্ষেত্রে উভয় অভিধানই একই দৈর্ঘ্যের। এবং তারা সর্বদা থাকবে, কারণ প্রোগ্রামটি এভাবেই কাজ করে।
ব্যবহারকারী225312

5
পাইথন ৩.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
আমি যখন এটি চালাই, তখনও আমি পরিবর্তিত মানগুলির সাথে লেনদেন করতে একটি ত্রুটি পেয়েছি: ভ্যালুআরার: একটি ডেটা ফ্রেমের সত্য মান অস্পষ্ট। A.empty, a.bool (), a.item (), a.ny () বা a.all () ব্যবহার করুন।
আফলাটাস

2
@ আফলাটাস - 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
আমি @ এরকিনএলপজুনির সাথে একমত নই আপনি একটি প্রমাণ প্রদান করতে পারেন?
কিউ লুও

4
আমি @ এরকিনএলপজুনির সাথে একমত নই। অফিসিয়াল ডকুমেন্টেশন দেখায় যে == প্রকৃত অর্থে অভিধানের সাথে মানের তুলনা করে, ঠিকানা দ্বারা নয়। docs.python.org/2/library/stdtyype.html#mapping-tyype-dict
ম্যাথু নাকায়মা

3
পাইথন ২..1.১৩ এর জন্য কাজ করে
জেসুইসমে

4
@ঙ্কোস্টিস:OrderedDict != dict
CONvid19

3
আপনি কি দয়া করে এমন কোনও ইনপুট সরবরাহ করতে পারেন যেখানে এটি সত্য নয়?
CONvid19

55

আমি অজগর থেকে নতুন কিন্তু আমি @ মওদাদের অনুরূপ কিছু করে শেষ করেছি

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

পরিদর্শনের জন্য ফলাফলটি সুন্দর-মুদ্রণের বিষয়ে নোট: উপরের কোডটি যদি উভয় ডিক্টের একই বৈশিষ্ট্য কী থাকে (উদাহরণ হিসাবে যেমন আলাদা আলাদা অ্যাট্রিবিউট মান সহ) ব্যবহার করে works তবে, যদি কোনও "extra"বৈশিষ্ট্য উপস্থিত থাকে তবে সেগুলির মধ্যে একটি হ'ল, 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
পাইথন ৩.৫ ব্যবহারকারী যে কোনও ব্যক্তির জন্য, cmpবিল্ট ইনটি সরিয়ে ফেলা হয়েছে (এবং এটি আগে সরানো হিসাবে বিবেচনা করা উচিত । একটি বিকল্প তারা প্রস্তাব দেয়: (a > b) - (a < b) == cmp(a, b)কার্যকরী সমতুল্য (বা আরও ভাল __eq__এবং __hash__) এর জন্য
নার্ডওয়ালার

3
@ আওয়ার্ডওয়ালার - ডিক্টগুলি অদৃশ্য প্রকারের নয়, সুতরাং ডিক্ট_এ> ডিক্ট_বি একটি উত্থাপন করবে TypeError:unorderable types: dict() < dict()
স্টেফানো

2
@ স্টেফানো: শুভ কল, আমার মন্তব্যটি পাইথনের সাধারণ তুলনার জন্য বেশি ছিল (আমি প্রকৃত উত্তরের দিকে মনোযোগ দিচ্ছিলাম না, আমার ভুলটি)।
নারডওয়লার

9

আপনি যদি ধরে নেন যে উভয় অভিধানেই কেবল সাধারণ মান রয়েছে। তবে আপনার যদি অভিধান থাকে তবে অভিধানগুলি হ্যাশেবল নয় বলে আপনি একটি ব্যতিক্রম পাবেন।

আমার মাথার উপরের অংশটি, এমন কিছু কাজ করতে পারে:

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 (ডিক্ট 1 [কী] == ডিক্ট 2 [কী]) , you can do সমস্ত (atleast_1d (ডিক্ট 1 [কী] == ডিক্ট 2 [কী])) এর ভিত্তিতে অন্যান্য শ্রেণিতে কাজ করবে ।
EL_DON

+1, তবে আপনার মিথ্যা হয়ে যাওয়ার সাথে for loopসাথে আপনি dicts_are_equalতার থেকে আলাদা হয়ে যেতে পারেন। আর কোনও চালিয়ে যাওয়ার দরকার নেই।
pfabri

6

অপর একটি সম্ভাবনা, ওপি-র শেষ নোট অবধি, জেএসওএন হিসাবে ফেলে দেওয়া ডিক্টের হ্যাশগুলি ( 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
@ ব্রুনো: ওপিকে উদ্ধৃত করে: "গতির চেয়ে ভাল না, আমি কোড কমনীয়তার কথা বলছি"
ওউজে

2
এটি মোটেও মার্জিত নয়, এটি অনিরাপদ বোধ করে এবং এটি একটি খুব সাধারণ সমস্যার জন্য অতিরিক্ত জটিল
ব্রুনো

7
@ ব্রুনো: কমনীয়তা বিষয়গত। আমি বুঝতে পারি যে আপনি এটি পছন্দ করেন না (এবং সম্ভবত নিম্নচোটিত)। এটি "ভুল" হিসাবে একই নয়।
ওউজে

4
এটি একটি দুর্দান্ত উত্তর। json.dumps(d, sort_keys=True)আপনাকে ক্যানোনিকাল জেএসএন দেবে যাতে আপনি নিশ্চিত হতে পারেন যে উভয় ডিক সমতুল্য। এছাড়াও এটি নির্ভর করে যে আপনি কী অর্জন করতে চাইছেন। যত তাড়াতাড়ি মান JSON সিরিজালাইজেবল না হয় এটি ব্যর্থ হবে। এইভাবে যারা এটি অকার্যকর বলে থাকেন, উজসন প্রকল্পটি দেখুন।
নাতিম

6

ফাংশনটি সূক্ষ্ম আইএমও, পরিষ্কার এবং স্বজ্ঞাত। তবে কেবল আপনাকে (অন্য) উত্তর দেওয়ার জন্য, এখানে আমার যেতে হবে:

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: "সেটে X1 (dict1.keys ()) ইউনিয়ন (dict2.keys ()) জন্য:।"
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)। এমনকি যখন আপনি একই ডিকটগুলি অন্য কোনও ক্রমে তুলনা করেন (শেষ উদাহরণ)। সর্বোত্তম জিনিসটি হ'ল এটি সম্পাদন করার জন্য আপনার তৃতীয় পক্ষের প্যাকেজ দরকার নেই।

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

আমার প্রতিক্রিয়াতে দেরি হওয়া আগের চেয়ে ভাল!

সমান তুলনা তুলনায় নোট_একুয়াল আরও দক্ষ। যেমন দুটি ডিক্ট সমান নয় যদি একটি ডিকের কোনও মূল মান অন্য ডিকের মধ্যে পাওয়া যায় না। নীচের কোডটি বিবেচনায় নিয়েছে যে আপনি সম্ভবত ডিফল্ট ডিকের তুলনা করছেন এবং এভাবে গেটাইটেমের পরিবর্তে গেট ব্যবহার করুন []।

প্রাপ্ত কলটিতে ডিফল্ট হিসাবে একধরনের এলোমেলো মান ব্যবহার করা কী-এর সমান পাওয়া যায় - কেবলমাত্র ডিক্টের যদি কোনও ডিকের মান হিসাবে কিছু না থাকে এবং অন্যটির মধ্যে কীটি বিদ্যমান না থাকে। এছাড়াও পান! = শর্তটি দক্ষতার জন্য শর্ত নয় এমন আগে পরীক্ষা করা হয় কারণ আপনি একই সাথে উভয় পক্ষের কী এবং মানগুলি পরীক্ষা করে নিচ্ছেন।

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

পাইউনাইটে একটি পদ্ধতি রয়েছে যা অভিধানগুলির সাথে সুন্দর তুলনা করে। আমি নিম্নলিখিত দুটি অভিধান ব্যবহার করে এটি পরীক্ষা করেছি এবং এটি আপনি যা খুঁজছেন ঠিক তা করে।

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আপনার প্রোডাকশন কোডে আমদানি করার পরামর্শ দিচ্ছি না । আমার ধারণা হ'ল পাইউনিতের উত্সটি আবার উত্পাদনে চালিত হতে পারে। এটি অভিধানগুলিকে pprintকোনটি "প্রিন্ট করে" ব্যবহার করে। এই কোডটিকে "উত্পাদন প্রস্তুত" হিসাবে অভিযোজিত করা বেশ সহজ বলে মনে হচ্ছে।


1

অভিধান দেখুন অবজেক্টগুলি দেখুন: https://docs.python.org/2/library/stdtyype.html#dict

আপনি ডিকটিভিউ 2 কে ডিকভিউ 1 থেকে বিয়োগ করতে পারবেন এবং এটি কী / মান জোড়াগুলির সেট সেট করবে যা ডিকভিউ 2-তে পৃথক:

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

পাইথন ৩.6 এ এটি করা যেতে পারে:

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

ret_1 পরিবর্তনশীলটি সত্য হবে যদি ডিক্টের সমস্ত আইটেম ডিক্ট 3 এ উপস্থিত থাকে


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

দুটি অভিধানের গভীর তুলনা করার সবচেয়ে সহজ উপায় (এবং এর মধ্যে আরও শক্তিশালী এক) সেগুলি জেএসএন ফর্ম্যাটে সিরিয়াল করা, কীগুলি বাছাই করা এবং স্ট্রিংয়ের ফলাফলগুলির সাথে তুলনা করা:

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.dumpsডিফল্ট সেটিংসের সাথে নির্ধারক হিসাবে )।
ড্যানিয়েল Farrell
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.