शब्दकोश को टटोलना?


156

कैशिंग प्रयोजनों के लिए मुझे GET तर्कों से एक कैश कुंजी उत्पन्न करने की आवश्यकता है जो एक तानाशाह में मौजूद हैं।

वर्तमान में मैं उपयोग कर रहा हूं sha1(repr(sorted(my_dict.items())))( sha1()एक आंतरिक विधि है जो हैशलीब का आंतरिक रूप से उपयोग करता है ), लेकिन अगर कोई बेहतर तरीका है तो मैं उत्सुक हूं।


4
यह नेस्टेड तानाशाह के साथ काम नहीं कर सकता है। सबसे छोटा समाधान इसके बजाय json.dumps (my_dict, Sort_keys = True) का उपयोग करना है, जो कि प्रमुख मानों की पुनरावृत्ति करेगा।
एंड्रे फेडोरोव

2
FYI करें: dumps, stackoverflow.com/a/12739361/1082367 कहते हैं, "अचार के उत्पादन को तानाशाही और समान आदेश के लिए गैर-नियतात्मक होने के समान कारणों के लिए विहित होने की गारंटी नहीं है। हैशिंग के लिए अचार या छाप या रीप्र का उपयोग न करें। । "
मैथ्यू कॉर्नेल

वस्तुओं को नहीं, तानाशाही कुंजियों को क्रमबद्ध करें, मैं भी हैश फ़ंक्शन के लिए कुंजियाँ भेजूँगा।
nyuwec

2
हैशिंग म्यूटेबल डेटा स्ट्रक्चर्स (जैसे शब्दकोशों) के बारे में दिलचस्प बैकस्टोरी: python.org/dev/peps/pep-0351 को मनमाने ढंग से ठंडी वस्तुओं की अनुमति देने का प्रस्ताव किया गया था, लेकिन खारिज कर दिया गया। तर्क के लिए, इस धागे को अजगर-देव में देखें: mail.python.org/pipermail/python-dev/2006-Febdays/060793.html
FluxLemur

यदि आपका डेटा json प्रारूप है, और आप शब्दार्थ रूप से अपरिष्कृत हैशिंग, चेकआउट github.com/schollii/sandals/blob/master/json_sem_hash.py चाहते हैं । यह नेस्टेड संरचनाओं पर काम करता है (निश्चित रूप से, जोंस के बाद से), और संरक्षित आदेश (जो कि अजगर के जीवनकाल में विकसित हुआ है) जैसे तानाशाही के आंतरिक पर निर्भर नहीं करता है, और दो डेटा संरचनाएं समान होने पर एक ही हैश देगा जैसा {'a': 1, 'b':2}शब्दार्थ वैसा ही है {'b':2, 'a':1})। मैंने इसे अभी तक बहुत जटिल कुछ भी YMMV पर उपयोग नहीं किया है, लेकिन प्रतिक्रिया का स्वागत है।
ओलिवर

जवाबों:


110

यदि आपके शब्दकोश में नेस्टेड नहीं है, तो आप तानाशाह की वस्तुओं और उपयोग के साथ एक फ्रेज़ेन्सेट बना सकते हैं hash():

hash(frozenset(my_dict.items()))

यह JSON स्ट्रिंग उत्पन्न करने या शब्दकोश के प्रतिनिधित्व की तुलना में बहुत कम कम्प्यूटेशनल रूप से गहन है।

अद्यतन: कृपया नीचे टिप्पणी देखें, क्यों यह दृष्टिकोण एक स्थिर परिणाम नहीं दे सकता है।


9
यह एक नेस्टेड शब्दकोश के साथ मेरे लिए काम नहीं किया। मैंने नीचे समाधान की कोशिश नहीं की है (बहुत जटिल)। ओपी का समाधान पूरी तरह से ठीक काम करता है। मैंने आयात को बचाने के लिए हैश के साथ sha1 प्रतिस्थापित किया।
स्पेल

9
@ किज़र काम नहीं करेगा क्योंकि टुपल का अर्थ है ऑर्डर देना लेकिन तानाशाह आइटम अनियंत्रित हैं। फ्रोज़ेनसेट बेहतर है।
एंटीमनी

28
बिल्ट-इन हैश से सावधान रहें यदि कुछ को अलग-अलग मशीनों के अनुरूप होना चाहिए। हेरोकू और जीएई जैसे क्लाउड प्लेटफार्मों पर अजगर के कार्यान्वयन अलग-अलग मूल्यों पर हैश () के लिए विभिन्न मूल्यों को वापस कर देगा, जो किसी भी चीज के लिए बेकार है जो दो या अधिक "मशीनों" के बीच साझा किया जाना चाहिए (हरोकू के मामले में डायनो
बेन रॉबर्ट्स

6
यह दिलचस्प हो सकता है कि hash()फ़ंक्शन एक स्थिर आउटपुट का उत्पादन नहीं करता है। इसका मतलब है कि, एक ही इनपुट को देखते हुए, यह एक ही अजगर इंटरप्रेटर के विभिन्न उदाहरणों के साथ अलग-अलग परिणाम देता है। मेरे लिए, ऐसा लगता है कि इंटरप्रेटर शुरू होने पर हर बार किसी प्रकार का बीज मूल्य उत्पन्न होता है।
हरमन शेखनर

7
अपेक्षित होना। बीज को सुरक्षा कारण के लिए पेश किया गया है जहाँ तक मुझे याद है कि मैं किसी प्रकार के मेमोरी रैंडमाइजेशन को जोड़ना चाहता हूं। तो आप उम्मीद नहीं कर सकते कि हैश दो अजगर प्रक्रियाओं के बीच एक ही होगा
निकोक्रॉक

137

का उपयोग करना sorted(d.items())हमें एक स्थिर repr पाने के लिए पर्याप्त नहीं है। मूल्यों में से कुछ dशब्दकोशों में भी हो सकते हैं, और उनकी चाबियाँ अभी भी एक अनियंत्रित क्रम में सामने आएंगी। जब तक सभी चाबियाँ तार हैं, मैं उपयोग करना पसंद करता हूं:

json.dumps(d, sort_keys=True)

उस ने कहा, अगर हैश को अलग-अलग मशीनों या पायथन संस्करणों में स्थिर होना चाहिए, तो मुझे यकीन नहीं है कि यह बुलेटप्रूफ है। आप किसी भी परिवर्तन से अपने आप को बचाने के लिए तर्क separatorsऔर ensure_asciiतर्क जोड़ना चाह सकते हैं । मैं टिप्पणियों की सराहना करता हूं।


6
यह सिर्फ विरोधाभास है, लेकिन JSON बिना किसी शाब्दिक भाग के अधिकांश पात्रों को दिखाने की अनुमति देता है, इसलिए एनकोडर को पात्रों के बचने के बारे में कुछ विकल्प बनाने या केवल उनके माध्यम से पास करने की अनुमति मिलती है। फिर जोखिम यह है कि एनकोडर के विभिन्न संस्करण (या भविष्य के संस्करण) डिफ़ॉल्ट रूप से अलग-अलग भागने के विकल्प बना सकते हैं, और फिर आपका प्रोग्राम विभिन्न वातावरणों में एक ही शब्दकोश के लिए अलग-अलग हैश मानों की गणना करेगा। ensure_asciiतर्क यह पूरी तरह काल्पनिक समस्या के खिलाफ की रक्षा करेंगे।
जैक ओ'कॉनर

4
मैंने अलग-अलग डेटासेट के साथ इसके प्रदर्शन का परीक्षण किया, यह इससे बहुत तेज है make_hashgist.github.com/charlax/b8731de51d2ea86c6eb9
charlax

3
@charlax ujson तानाशाह जोड़ों के आदेश की गारंटी नहीं देता है, इसलिए ऐसा करना सुरक्षित नहीं है
arthurprs

11
यह समाधान केवल तब तक काम करता है जब तक सभी कुंजी स्ट्रिंग हैं, जैसे json.dumps ({'a': {(0, 5): 5, 1: 3}}) विफल।
केडे

5
@LorenzoBelli, आप जोड़कर वह दूर कर सकते हैं default=strकरने के लिए dumpsआदेश। अच्छी तरह से काम करने लगता है।
mlissner

63

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

यद्यपि एक उत्तर को स्वीकार कर लिया गया है, प्रश्न का शीर्षक "हैशिंग ए डिक्शनरी डिक्शनरी" है, और यह उत्तर उस शीर्षक के संबंध में अधूरा है। (जैसा कि प्रश्न के शरीर के संबंध में है, उत्तर पूर्ण है।)

नेकड डिक्शनरी

यदि कोई शब्दकोश को हैश करने के लिए स्टैक ओवरफ्लो की खोज करता है, तो कोई इस शीर्षक वाले प्रश्न पर ठोकर खा सकता है, और यदि कोई हैश के लिए नेस्टेड शब्दकोशों का प्रयास कर रहा है तो असंतुष्ट छोड़ दें। उपरोक्त उत्तर इस मामले में काम नहीं करेगा, और आपको हैश को पुनः प्राप्त करने के लिए किसी प्रकार के पुनरावर्ती तंत्र को लागू करना होगा।

यहाँ एक ऐसा तंत्र है:

import copy

def make_hash(o):

  """
  Makes a hash from a dictionary, list, tuple or set to any level, that contains
  only other hashable types (including any lists, tuples, sets, and
  dictionaries).
  """

  if isinstance(o, (set, tuple, list)):

    return tuple([make_hash(e) for e in o])    

  elif not isinstance(o, dict):

    return hash(o)

  new_o = copy.deepcopy(o)
  for k, v in new_o.items():
    new_o[k] = make_hash(v)

  return hash(tuple(frozenset(sorted(new_o.items()))))

बोनस: वस्तुओं और कक्षाओं का सामना करना

hash()समारोह अच्छा काम करता है जब आप वर्ग या उदाहरणों हैश। हालाँकि, यहाँ एक मुद्दा है जो मुझे हैश के साथ मिला, जैसा कि वस्तुओं के संबंध में है:

class Foo(object): pass
foo = Foo()
print (hash(foo)) # 1209812346789
foo.a = 1
print (hash(foo)) # 1209812346789

हैश भी ऐसा ही है, यहां तक ​​कि मैंने फू फू करने के बाद भी। ऐसा इसलिए है क्योंकि फू की पहचान नहीं बदली है, इसलिए हैश वही है। यदि आप अपनी वर्तमान परिभाषा के आधार पर अलग से हैश का फू चाहते हैं, तो समाधान वास्तव में बदल रहा है जो कुछ भी हैश को बंद करना है। इस मामले में, __dict__विशेषता:

class Foo(object): pass
foo = Foo()
print (make_hash(foo.__dict__)) # 1209812346789
foo.a = 1
print (make_hash(foo.__dict__)) # -78956430974785

काश, जब आप कक्षा के साथ ही काम करने का प्रयास करते हैं:

print (make_hash(Foo.__dict__)) # TypeError: unhashable type: 'dict_proxy'

वर्ग __dict__संपत्ति एक सामान्य शब्दकोष नहीं है:

print (type(Foo.__dict__)) # type <'dict_proxy'>

यहाँ पिछले जैसा ही एक तंत्र है जो उचित रूप से कक्षाओं को संभालेगा:

import copy

DictProxyType = type(object.__dict__)

def make_hash(o):

  """
  Makes a hash from a dictionary, list, tuple or set to any level, that 
  contains only other hashable types (including any lists, tuples, sets, and
  dictionaries). In the case where other kinds of objects (like classes) need 
  to be hashed, pass in a collection of object attributes that are pertinent. 
  For example, a class can be hashed in this fashion:

    make_hash([cls.__dict__, cls.__name__])

  A function can be hashed like so:

    make_hash([fn.__dict__, fn.__code__])
  """

  if type(o) == DictProxyType:
    o2 = {}
    for k, v in o.items():
      if not k.startswith("__"):
        o2[k] = v
    o = o2  

  if isinstance(o, (set, tuple, list)):

    return tuple([make_hash(e) for e in o])    

  elif not isinstance(o, dict):

    return hash(o)

  new_o = copy.deepcopy(o)
  for k, v in new_o.items():
    new_o[k] = make_hash(v)

  return hash(tuple(frozenset(sorted(new_o.items()))))

आप इसका उपयोग कर सकते हैं हालांकि आप चाहते हैं कि कई तत्वों की हैश टपल वापस करने के लिए:

# -7666086133114527897
print (make_hash(func.__code__))

# (-7666086133114527897, 3527539)
print (make_hash([func.__code__, func.__dict__]))

# (-7666086133114527897, 3527539, -509551383349783210)
print (make_hash([func.__code__, func.__dict__, func.__name__]))

नोट: उपरोक्त सभी कोड पायथन 3.x को मानता है। पहले के संस्करणों में परीक्षण नहीं किया था, हालांकि मुझे लगता है make_hash()कि 2.7.2 में काम करेंगे। जहां तक ​​उदाहरणों को काम करने की बात है, तो मुझे यह पता है

func.__code__ 

के साथ प्रतिस्थापित किया जाना चाहिए

func.func_code

आइंस्टीन दूसरे तर्क के लिए एक अनुक्रम लेता है, इसलिए आइंस्टीनेंस (ओ, (सेट, ट्यूपल, सूची)) काम करेगा।
Xealot

बनाने के लिए धन्यवाद मुझे एहसास हुआ कि फ्रेज़ेन्सेट लगातार हैश
क्वेरिस्ट्रिंग

1
> वापसी हैश (टपल (frozenset (अनुसार क्रमबद्ध (new_o.items ())))) - आइटम आदेश में एक ही हैश बनाने के लिए हल हो सकता है अगर dict आइटम आदेश अलग है, लेकिन कुंजी मान नहीं हैं की जरूरत है
बस Koopmans

अच्छा! मैंने hashसूचियों और टुपल्स के साथ एक कॉल भी जोड़ा । अन्यथा यह पूर्णांक की मेरी सूची लेता है जो मेरे शब्दकोश में मान होता है, और हैश की सूची वापस करता है, जो कि मैं नहीं चाहता।
osa

एक फ्रोज़ेनसेट एक संग्रहित संग्रह है, इसलिए इसके इनपुट को छाँटने से कुछ हासिल नहीं होता है। दूसरी ओर सूचियाँ और टुपल्स ORDERED संग्रह ("अनुक्रम") हैं, और इसलिए हैश मान को आइटम के क्रम से प्रभावित किया जाना चाहिए। आप उन्हें सॉर्ट नहीं करना चाहिए!
रॉबॉम

14

यहाँ एक स्पष्ट समाधान है।

def freeze(o):
  if isinstance(o,dict):
    return frozenset({ k:freeze(v) for k,v in o.items()}.items())

  if isinstance(o,list):
    return tuple([freeze(v) for v in o])

  return o


def make_hash(o):
    """
    makes a hash out of anything that contains only list,dict and hashable types including string and numeric types
    """
    return hash(freeze(o))  

यदि आप बदलते if isinstance(o,list):हैं if isinstance(obj, (set, tuple, list)):तो यह फ़ंक्शन किसी भी वस्तु पर काम कर सकता है।
पीटर शोर्न

10

नीचे दिया गया कोड पायथन हैश () फ़ंक्शन का उपयोग करने से बचता है क्योंकि यह हैश प्रदान नहीं करेगा जो कि पायथन के पुनरारंभ के अनुरूप है (देखें पायथन 3.3 में हैश फ़ंक्शन सत्रों के बीच अलग-अलग परिणाम देता है )। make_hashable()ऑब्जेक्ट को नेस्टेड टुपल्स में make_hash_sha256()परिवर्तित करेगा और repr()बेस 64 एनकोडेड SHA256 हैश में भी परिवर्तित करेगा ।

import hashlib
import base64

def make_hash_sha256(o):
    hasher = hashlib.sha256()
    hasher.update(repr(make_hashable(o)).encode())
    return base64.b64encode(hasher.digest()).decode()

def make_hashable(o):
    if isinstance(o, (tuple, list)):
        return tuple((make_hashable(e) for e in o))

    if isinstance(o, dict):
        return tuple(sorted((k,make_hashable(v)) for k,v in o.items()))

    if isinstance(o, (set, frozenset)):
        return tuple(sorted(make_hashable(e) for e in o))

    return o

o = dict(x=1,b=2,c=[3,4,5],d={6,7})
print(make_hashable(o))
# (('b', 2), ('c', (3, 4, 5)), ('d', (6, 7)), ('x', 1))

print(make_hash_sha256(o))
# fyt/gK6D24H9Ugexw+g3lbqnKZ0JAcgtNW+rXIDeU2Y=

1
make_hash_sha256(((0,1),(2,3)))==make_hash_sha256({0:1,2:3})==make_hash_sha256({2:3,0:1})!=make_hash_sha256(((2,3),(0,1)))। यह काफी समाधान नहीं है जिसकी मुझे तलाश है, लेकिन यह एक अच्छा मध्यवर्ती है। मैं type(o).__name__भेदभाव को मजबूर करने के लिए प्रत्येक टुपल्स की शुरुआत में जोड़ने के बारे में सोच रहा हूं ।
पोख

यदि आप सूची को भी क्रमबद्ध करना चाहते हैं:tuple(sorted((make_hashable(e) for e in o)))
सूरज

make_hash_sha256 () - अच्छा!
jtlz2

1
@ सूरज आपको हैशिंग से पहले सूची को क्रमबद्ध नहीं करना चाहिए क्योंकि विभिन्न क्रमों में उनकी सामग्री वाली सूचियाँ निश्चित रूप से एक ही बात नहीं हैं। यदि आइटम का क्रम मायने नहीं रखता है तो समस्या यह है कि आप गलत डेटा संरचना का उपयोग कर रहे हैं। आपको सूची के बजाय सेट का उपयोग करना चाहिए।
स्कॉचक्लो

@scottclowe यह बहुत सच है। उस बिंदु को जोड़ने के लिए धन्यवाद। 2 परिदृश्य हैं जहां आप अभी भी एक सूची चाहते हैं (विशिष्ट आदेश की आवश्यकता के बिना) - 1. दोहराई जाने वाली वस्तुओं की सूची। 2. जब आप सीधे JSON का उपयोग करना चाहते हैं। जैसा कि JSON "सेट" प्रतिनिधित्व का समर्थन नहीं करता है।
सूरज

5

2013 के उत्तर से अपडेट किया गया ...

उपरोक्त कोई भी उत्तर मुझे विश्वसनीय नहीं लगता। इसका कारण वस्तुओं का उपयोग () है। जहाँ तक मुझे पता है, यह मशीन-निर्भर क्रम में सामने आता है।

इसके बजाय इसके बारे में कैसे?

import hashlib

def dict_hash(the_dict, *ignore):
    if ignore:  # Sometimes you don't care about some items
        interesting = the_dict.copy()
        for item in ignore:
            if item in interesting:
                interesting.pop(item)
        the_dict = interesting
    result = hashlib.sha1(
        '%s' % sorted(the_dict.items())
    ).hexdigest()
    return result

आपको क्यों लगता है कि यह मायने रखता है जो dict.itemsएक अनुमानित क्रमबद्ध सूची नहीं लौटाता है? frozensetउस की देखभाल करता है
ग्लोरन

2
एक सेट, परिभाषा के अनुसार, अनियंत्रित है। इस प्रकार जिस क्रम में वस्तुओं को जोड़ा जाता है वह अप्रासंगिक है। आपको यह महसूस करना होगा कि बिल्ट-इन फ़ंक्शन hashइस बात की परवाह नहीं करता है कि फ्रोज़ेनसेट की सामग्री कैसे छपी है या ऐसा कुछ है। कई मशीनों और अजगर संस्करणों में इसका परीक्षण करें और आप देखेंगे।
ग्लारन

आप मूल्य = हैश ('% s ::% s'% (मान, प्रकार (मान))) में अतिरिक्त हैश () कॉल का उपयोग क्यों करते हैं ??
रुईदो

4

कुंजी आदेश को संरक्षित करने के लिए, hash(str(dictionary))या इसके बजाय hash(json.dumps(dictionary))मैं त्वरित और गंदे समाधान पसंद करूंगा:

from pprint import pformat
h = hash(pformat(dictionary))

यह उन प्रकारों के लिए भी काम करेगा जैसे DateTimeऔर अधिक जो JSON क्रमिक नहीं हैं।


3
कौन गारंटी देता है कि पफॉर्मेट या जसन हमेशा एक ही क्रम का उपयोग करते हैं?
ThiefMaster

1
@ThiefMaster, "संस्करण 2.5 में परिवर्तित किया गया: डिसप्ले को कंप्लीट करने से पहले डिक्शनरों को कुंजी द्वारा सॉर्ट किया जाता है। 2.5 से पहले, एक डिक्शनरी को केवल तब ही सॉर्ट किया जाता है, जब उसके डिसप्ले को एक से अधिक लाइन की आवश्यकता होती है, हालाँकि यह डॉक्यूमेंट नहीं था।" ( डॉक्सथॉन) org / 2 / पुस्तकालय / pprint.html )
Arel

2
यह मुझे मान्य नहीं लगता है। प्रिन्ट मॉड्यूल और पफॉर्मेट को लेखकों द्वारा प्रदर्शन उद्देश्यों के लिए समझा जाता है न कि क्रमांकन के लिए। इस वजह से, आपको यह मानने में सुरक्षित महसूस नहीं करना चाहिए कि पफॉर्मेट हमेशा एक परिणाम देगा जो काम करता है।
डेविड सैंडर्स

3

आप अपने डिक्ट्री को फ्रीज करने और इसे हैशेबल बनाने के लिए थर्ड-पार्टी frozendictमॉड्यूल का उपयोग कर सकते हैं ।

from frozendict import frozendict
my_dict = frozendict(my_dict)

नेस्टेड ऑब्जेक्ट्स को संभालने के लिए, आप इसके साथ जा सकते हैं:

import collections.abc

def make_hashable(x):
    if isinstance(x, collections.abc.Hashable):
        return x
    elif isinstance(x, collections.abc.Sequence):
        return tuple(make_hashable(xi) for xi in x)
    elif isinstance(x, collections.abc.Set):
        return frozenset(make_hashable(xi) for xi in x)
    elif isinstance(x, collections.abc.Mapping):
        return frozendict({k: make_hashable(v) for k, v in x.items()})
    else:
        raise TypeError("Don't know how to make {} objects hashable".format(type(x).__name__))

यदि आप अधिक प्रकारों का समर्थन करना चाहते हैं, तो उपयोग करें functools.singledispatch(Python 3.7):

@functools.singledispatch
def make_hashable(x):
    raise TypeError("Don't know how to make {} objects hashable".format(type(x).__name__))

@make_hashable.register
def _(x: collections.abc.Hashable):
    return x

@make_hashable.register
def _(x: collections.abc.Sequence):
    return tuple(make_hashable(xi) for xi in x)

@make_hashable.register
def _(x: collections.abc.Set):
    return frozenset(make_hashable(xi) for xi in x)

@make_hashable.register
def _(x: collections.abc.Mapping):
    return frozendict({k: make_hashable(v) for k, v in x.items()})

# add your own types here

यह काम नहीं करता है, उदाहरण के लिए, एक के लिए dictकी DataFrameवस्तुओं।
जेम्स हिर्सचोर्न

@JamesHirschorn: ज़ोर से विफल करने के लिए अद्यतन
एरिक

बेहतर! मैंने निम्नलिखित elifखंड को DataFrameएस के साथ काम करने के लिए जोड़ा : elif isinstance(x, pd.DataFrame): return make_hashable(hash_pandas_object(x).tolist()) मैं उत्तर को संपादित करूंगा और देखूंगा कि क्या आप इसे स्वीकार करते हैं ...
जेम्स हिर्सचोर्न

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

1
hashरैंडमाइजेशन जानबूझकर सुरक्षा सुविधा है जो डिफ़ॉल्ट रूप से अजगर 3.7 में सक्षम है।
एरिक

1

ऐसा करने के लिए आप मैप्स लाइब्रेरी का उपयोग कर सकते हैं । विशेष रूप से, map.FrozenMap

import maps
fm = maps.FrozenMap(my_dict)
hash(fm)

स्थापित करने के लिए maps, बस करें:

pip install maps

यह नेस्टेड dictकेस को भी हैंडल करता है:

import maps
fm = maps.FrozenMap.recurse(my_dict)
hash(fm)

अस्वीकरण: मैं mapsपुस्तकालय का लेखक हूं ।


पुस्तकालय एक सूची के अंदर सूची को सॉर्ट नहीं करता है। और इसलिए यह अलग हैश का उत्पादन कर सकता है। सूची को छाँटने का विकल्प भी होना चाहिए। एक फ्रेज़ेन्सेट को मदद करनी चाहिए, लेकिन मुझे आश्चर्य है कि आप नेस्टेड डिक्टेट के साथ मामले को कैसे संभालेंगे, जिसमें डिक्ट्स की सूची होगी। जैसा कि तानाशाह अप्राप्य हैं।
सूरज

1
@ सूरज: यह नेस्टेड स्ट्रक्चर को हैंडल करता है.recurseMaps.readthedocs.io/en/latest/api.html#maps.FrozenMap.recurse देखें । सूचियों में आदेश देना शब्दार्थ है, यदि आप स्वतंत्रता चाहते हैं तो आप अपनी सूचियों को कॉलिंग से पहले सेट करने के लिए परिवर्तित कर सकते हैं .recurse। ( list_fn.recursetuplefrozenset
.Eg

0

समस्या से संपर्क करने का एक तरीका यह है कि शब्दकोश के आइटमों का एक हिस्सा बनाया जाए:

hash(tuple(my_dict.items()))

-8

मैं इसे इस तरह से करता हूं:

hash(str(my_dict))

1
क्या कोई समझा सकता है कि इस पद्धति में क्या गलत है?
12

7
@maximi डिक्शनरी इसे ऑर्डर की शर्तों के अनुसार स्थिर नहीं करती है, इस प्रकार hash(str({'a': 1, 'b': 2})) != hash(str({'b': 2, 'a': 1}))(जबकि यह कुछ शब्दकोशों के लिए काम कर सकती है, यह सभी के लिए काम करने की गारंटी नहीं है)।
व्लाद फ्रलोव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.