2009-08-09 7 views
45

में कोई ऑब्जेक्ट अद्वितीय पहचानकर्ता है, यह java.lang.Object.hashcode() विधि के समान होगा।क्या पाइथन

मैं एक सेट में वस्तुओं मैं कोई नियंत्रण नहीं है की दुकान है, और सुनिश्चित करें कि केवल यदि दो वस्तुओं वास्तव में एक ही वस्तु हैं (एक ही मूल्यों को शामिल नहीं) मान ओवरराइट किया जाएगा बनाने की जरूरत है।

+5

नोट hashCode() '' कि जावा में निश्चित रूप से अनन्य नहीं है इस व्यवहार को साबित करने के हैश ओवरराइड करने के लिए नहीं है, यह सिर्फ है कुछ ध्यान से चुना 'बराबर() 'के संयोजन के साथ अर्थशास्त्र। – Joey

+0

और जैसा कि नीचे पोस्ट किया गया है पाइथन के 'हैश() 'में ** बिल्कुल ** समान शब्द हैं जो' java.lang.Object.hashcode()' के रूप में हैं। –

उत्तर

70
id(x) 

आपके लिए चाल करेगा। लेकिन मैं उत्सुक हूं, वस्तुओं के सेट के बारे में क्या गलत है (जो वस्तुओं को मूल्य से जोड़ती है)?

आपकी विशेष समस्या के लिए मैं शायद आईडी या रैपर ऑब्जेक्ट्स का सेट रखूंगा। एक रैपर ऑब्जेक्ट में एक संदर्भ होगा और x==y < ==>x.ref is y.ref से तुलना करेगा।

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

+1

डाउन-वोटिंग एक, क्योंकि आईडी (x) प्रत्येक ऑब्जेक्ट के लिए विशिष्टता सुनिश्चित नहीं करता है। ओपी बहुत स्पष्ट था कि वह * अलग * होने के लिए एक ही मूल्य वाले विभिन्न वस्तुओं का इलाज करना चाहता है। – Roy

+2

@ रॉय इसके विपरीत [डॉक्स] (https://docs.python.org/2/library/functions.html#id) कहता है कि 'id (x)' _is_ "इस ऑब्जेक्ट के लिए अद्वितीय और स्थिर होने की गारंटी है अपने जीवनकाल के दौरान "जिसके परिणामस्वरूप अलग-अलग ऑब्जेक्ट्स के साथ अलग-अलग ऑब्जेक्ट होते हैं (जब तक वे दोनों एक ही समय में मौजूद होते हैं) जिससे ओपी को वही करना चाहिए जो वे चाहते थे। – sparrowt

+0

@ sparrowt मैं देखता हूं। मैं आपसे सहमत हूं।मुख्य बिंदु यह है कि "आईडी अद्वितीय हो * जब एक ही मान के साथ दो वस्तु सह-मौजूद * * हो। 'id()' वही मान के साथ बार-बार बनाई गई (और नष्ट) वस्तुओं के लिए एक ही आईडी लौटता प्रतीत होता है, इसलिए मेरी मूल टिप्पणी है, लेकिन वास्तव में यह ठीक है, क्योंकि ओपी ने कहा है कि ऑब्जेक्ट्स सह-अस्तित्व में होने पर आईडी अद्वितीय होनी चाहिए। मेरे डाउन-वोट को हटा रहा है। – Roy

18

यही है "is" के लिए है।

के बजाय परीक्षण "if a == b" है, जो एक ही मूल्य के लिए परीक्षण,

परीक्षण "if a is b" है, जो एक ही पहचानकर्ता के लिए परीक्षण किया जाएगा।

+17

क्या यह कहना सही होगा कि पायथन का "है" जावा की "==" और पायथन की "==" जावा की "बराबर()" की तरह है? – MatrixFrog

+9

@MatrixFrog हां। – Imagist

1

आईला एन उल्लेख के रूप में, आईडी (एक्स) किसी ऑब्जेक्ट के लिए एक अद्वितीय पहचानकर्ता उत्पन्न करता है।

लेकिन आपके सवाल का भ्रामक है, के बाद से जावा के hashCode विधि एक अद्वितीय पहचानकर्ता नहीं देता है। जावा का हैशकोड अधिकांश हैश फ़ंक्शंस की तरह काम करता है: यह हमेशा एक ही ऑब्जेक्ट के लिए समान मान देता है, दो ऑब्जेक्ट्स बराबर बराबर बराबर कोड प्राप्त करते हैं, और असमान हैश मान असमान हैश कोड दर्शाते हैं। विशेष रूप से, दो अलग और असमान वस्तुओं को एक ही मूल्य मिल सकता है।

यह भ्रामक है क्योंकि क्रिप्टोग्राफिक हैश कार्यों अधिक (हालांकि वास्तव में नहीं) "विशिष्ट आईडी" है कि आप के लिए कहा इस तरह से काफी अलग हैं, और।

जावा की हैशकोड विधि के पाइथन समतुल्य हैश (x) है।

+0

यही कारण है कि मैंने स्पष्ट रूप से java.lang.Object की हैशकोड विधि का उल्लेख किया है। जो, डिफ़ॉल्ट रूप से, उस वस्तु के लिए एक अद्वितीय लंबा उत्पादन करता है। मुझे हैशकोड के अन्य कार्यान्वयन का एहसास हो सकता है, और कर सकता है, अलग है। – oneself

+0

लेकिन यह बात है: हैशकोड एक अद्वितीय लंबा उत्पादन नहीं करता है। यह लंबे समय तक उत्पादन करता है जो टकराव न करने की कोशिश करता है, लेकिन आप तारों को लंबे समय तक मैप नहीं कर सकते हैं और एक अद्वितीय मूल्य उत्पन्न कर सकते हैं। –

+1

... और पुराना धागा मुझे पता है। लेकिन मैं यह इंगित करना चाहता था कि आईडी() केवल अनूठी है जबकि दोनों ऑब्जेक्ट अभी भी मौजूद हैं। एक बार मुक्त हो जाने पर, आईडी को किसी अन्य ऑब्जेक्ट को सौंपा जा सकता है "गैर-ओवरलैपिंग लाइफटाइम वाले दो ऑब्जेक्ट्स में एक ही आईडी() मान हो सकता है।" [लिंक] (https://docs.python.org/2/library/functions.html#id) –

-1

आपको उन्हें सेट में रखने से पहले वस्तुओं की तुलना करने की आवश्यकता नहीं है। सेट() अर्थशास्त्र पहले से ही इसका ख्याल रखता है।

class A(object): 
    a = 10 
    b = 20 
    def __hash__(self): 
     return hash((self.a, self.b)) 

    a1 = A() 
    a2 = A() 
    a3 = A() 
    a4 = a1 
    s = set([a1,a2,a3,a4]) 
    s 
=> set([<__main__.A object at 0x222a8c>, <__main__.A object at 0x220684>, <__main__.A object at 0x22045c>]) 

ध्यान दें: आप वास्तव में :-)

+1

आपका समाधान उस वर्ग की तरह निर्भर करता है जो विरासत में मिला है: 'कक्षा बी (str): pass' अगर कॉल किया जाता है 'सेट ([बी(), बी()] के साथ) 'सेट' (['']) 'की ओर जाता है। शब्दकोशों से पहचान आम तौर पर वस्तुओं के लिए 'आईडी (एक्स)' पर निर्भर करती है, आपको इसे स्पष्ट रूप से उपयोग करना चाहिए और कोने के मामलों से बचना चाहिए। – Arne

+0

@ArneRecknagel आप सही हैं। लेकिन आईडी (x) की जांच के बाद आप एक सेट में क्या रखेंगे? – user942640