2010-08-11 8 views
34

के बारे में "हैशबल" पूछना मुझे एक मनमाना निर्देश लेने और इसे एक नए नियम में कॉपी करने में दिलचस्पी है, इसे रास्ते में बदलना।पाइथन मूल्य

एक उत्परिवर्तन मैं करना चाहता हूं स्वैप कुंजी और मूल्य है। दुर्भाग्यवश, कुछ मूल्य अपने अधिकार में डिक्ट्स हैं। हालांकि, यह एक "unhashable प्रकार: 'dict'" त्रुटि उत्पन्न करता है। मुझे वास्तव में मूल्य को स्ट्रिंग करने और इसे कुंजी देने में कोई फर्क नहीं पड़ता। लेकिन, मैं इस तरह कुछ करने के लिए सक्षम होने के लिए करना चाहते हैं:

for key in olddict: 
    if hashable(olddict[key]): 
    newdict[olddict[key]] = key 
    else 
    newdict[str(olddict[key])] = key 

वहाँ एक अपवाद नहीं फँसाने और "unhashable प्रकार" के लिए संदेश स्ट्रिंग को पार्स शामिल है कि यह करने के लिए एक साफ रास्ता नहीं है ? __hash__ के लिए दस्तावेज में

import collections 
>>> isinstance({}, collections.Hashable) 
False 
>> isinstance(0, collections.Hashable) 
True 

यह दृष्टिकोण भी उल्लेख किया गया है संक्षेप में:

उत्तर

38

अजगर 2.6 जब से तुम सार आधार वर्ग collections.Hashable उपयोग कर सकते हैं।

Doing so means that not only will instances of the class raise an appropriate TypeError when a program attempts to retrieve their hash value, but they will also be correctly identified as unhashable when checking isinstance(obj, collections.Hashable) (unlike classes which define their own __hash__() to explicitly raise TypeError).

+6

क्या यह काम करता है यदि एक टुपल में सूची/शब्दकोश होता है? –

+4

नहीं, और यह ऐसा कुछ है जिसे आप केवल रन-टाइम पर निर्धारित कर सकते हैं क्योंकि सूची की सामग्री आम तौर पर अज्ञात होती है। 'हैश (([],))' टाइप टाइपर: अवांछनीय प्रकार: 'सूची'' – Syncopated

+1

पायथन 2.7 'इंस्टेंसेंस (बाइटियर्रे ([0xa]), संग्रह। हैशबल का उपयोग करने वाले लोगों के लिए छोटी चेतावनी)'' सत्य 'लौटाता है लेकिन 'हैश (बाइटियर ([0xa]))' टाइप एरर: असहनीय प्रकार: 'bytearray' 'के साथ विफल रहता है। – RedX

13
def hashable(v): 
    """Determine whether `v` can be hashed.""" 
    try: 
     hash(v) 
    except TypeError: 
     return False 
    return True 
+3

नेड - यह वही है जो मैं टालना पसंद करूंगा। साथ ही, यह फ़ंक्शन TypeErrors को फंस जाएगा जो "अवांछनीय प्रकार" नहीं हैं। –

+5

केवल एक ही टाइपर है कि हैश() उठाएगा। या वैकल्पिक रूप से, जो भी टाइपरर हैश उठाता है, वह आपके मूल्य को धोने से रोक देगा। मैं यह भी तर्क दूंगा कि इसे अपवाद पकड़ना चाहिए, क्योंकि इससे कोई फर्क नहीं पड़ता कि हैश() असफल क्यों है: हैश() में विफलता आपके मूल्य को अचूक बनाती है। क्या आप इस बारे में और अधिक कह सकते हैं कि आप इस तरह के अपवादों से क्यों बचना चाहते हैं? यह एक अच्छा फ़ंक्शन में अपवाद हैंडलिंग को समाहित करता है, और आपका नमूना कोड पूरी तरह से काम से ऊपर बनाता है। –

+1

शायद यह एक दार्शनिक बिंदु से अधिक है - प्रश्न किसी प्रकार की "सनकी स्थिति" के कारण अप्रत्याशित होने की "असाधारण स्थिति" के बारे में नहीं है, लेकिन एक प्रकार पर उपलब्ध कार्यक्षमता के बारे में एक प्रश्न है। यदि इसका कोई मतलब निकले तो। –

1

पाइथन वस्तुओं में निर्मित सभी हैशबल .__hash__() विधि है। आप इसके लिए जांच सकते हैं।

olddict = {"a":1, "b":{"test":"dict"}, "c":"string", "d":["list"] } 

for key in olddict: 
    if(olddict[key].__hash__): 
     print str(olddict[key]) + " is hashable" 
    else: 
     print str(olddict[key]) + " is NOT hashable" 

उत्पादन

1 is hashable 
string is hashable 
{'test': 'dict'} is NOT hashable 
['list'] is NOT hashable 
+1

इस बारे में एक चेतावनी मिलती है: पायथन 2.5 में यह दिया जाएगा:' { 'टेस्ट': 'dict'} हैशबल है।यदि कोई वर्ग टाइपरर बढ़ाने के लिए '__hash__' को परिभाषित करता है तो यह नए संस्करणों में गलत परिणाम भी दे सकता है। –

0

क्यों बतख टाइपिंग का उपयोग नहीं?

for key in olddict: 
    try: 
     newdict[olddict[key]] = key 
    except TypeError: 
     newdict[str(olddict[key])] = key