python - ऑर्डर्ड डिक्ट के मूल्य बराबर क्यों नहीं हैं?




python-3.x dictionary (2)

पायथन 3 के साथ:

>>> from collections import OrderedDict
>>> d1 = OrderedDict([('foo', 'bar')])
>>> d2 = OrderedDict([('foo', 'bar')])

मैं समानता की जांच करना चाहता था:

>>> d1 == d2
True
>>> d1.keys() == d2.keys()
True

परंतु:

>>> d1.values() == d2.values()
False

क्या आप जानते हैं कि मूल्य बराबर क्यों नहीं हैं?

मैंने इसका परीक्षण पायथन 3.4 और 3.5 के साथ किया है।

इस सवाल के बाद, मैंने अतिरिक्त विवरण रखने के लिए पायथन-विचार मेलिंग सूची पर पोस्ट किया:

https://mail.python.org/pipermail/python-ideas/2015-December/037472.html


Python3 में, d1.values() और d2.values() collections.abc.ValuesView हैं d2.values() ऑब्जेक्ट्स:

>>> d1.values()
ValuesView(OrderedDict([('foo', 'bar')]))

उन्हें किसी ऑब्जेक्ट के रूप में तुलना न करें, सी उन्हें सूचियों पर घुमाएं और फिर उनकी तुलना करें:

>>> list(d1.values()) == list(d2.values())
True

जांच करना क्यों यह कुंजी की तुलना करने के लिए काम करता है, _collections_abc.py के _collections_abc.py में, KeysView Set से विरासत में है जबकि ValuesView नहीं करता है:

class KeysView(MappingView, Set):

class ValuesView(MappingView):
  • ValuesView और उसके माता-पिता में ValuesView लिए ट्रेसिंग:

    MappingView ==> Sized ==> ABCMeta ==> type ==> object

    __eq__ केवल object में लागू किया गया object और ओवरराइड नहीं किया गया है।

  • दूसरी तरफ, __eq__ सीधे Set से __eq__ करता है।


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

odict.keys / dict.keys और odict.items / dict.items :

  • odict.keys ( odict.keys उप-वर्ग ) collections.abc.Set . dict.keys (यह एक सेट-जैसी ऑब्जेक्ट) के अनुरूप होने के कारण तुलना का समर्थन करता है। यह इस तथ्य के कारण संभव है कि एक शब्दकोश (आदेश दिया गया या नहीं) के अंदर keys अद्वितीय और हर्षनीय होने की गारंटी दी जाती हैं।
  • odict.items ( odict.items उप-वर्ग ) dict.items के समान कारण के लिए तुलना का भी समर्थन करता है। itemsview को ऐसा करने की इजाजत है क्योंकि यह item में से एक है (विशेष रूप से, मूल्य का प्रतिनिधित्व करने वाला दूसरा तत्व) हैशबल नहीं है, विशिष्टता की गारंटी है, हालांकि ( keys अद्वितीय होने के कारण):

    >>> od = OrderedDict({'a': []})
    >>> set() & od.items()
    TypeErrorTraceback (most recent call last)
    <ipython-input-41-a5ec053d0eda> in <module>()
    ----> 1 set() & od.items()
    
    TypeError: unhashable type: 'list'
    

    इन दोनों दृश्यों के लिए keys , items , तुलना एक सरल कार्य का उपयोग करती है जिसे all_contained_in (सुंदर पठनीय) कहा जाता है जो वस्तुओं को __contain__ विधि का उपयोग करता है ताकि शामिल विचारों में तत्वों की सदस्यता की जांच हो सके।

अब, odict.values / dict.values बारे में:

  • जैसा कि देखा गया है, odict.values ( dict.values [shocker] का उप-वर्ग ) एक सेट-जैसी ऑब्जेक्ट की तरह तुलना नहीं करता है । ऐसा इसलिए है क्योंकि किसी valuesview के values को सेट के रूप में प्रदर्शित नहीं किया जा सकता है, कारण दो गुना हैं:

    1. सबसे महत्वपूर्ण बात यह है कि दृश्य में डुप्लिकेट हो सकते हैं जिन्हें हटाया नहीं जा सकता है।
    2. दृश्य में गैर-धब्बेदार वस्तुएं हो सकती हैं (जो, स्वयं पर, दृश्य को इस तरह के इलाज के रूप में पर्याप्त नहीं है)।

जैसा कि user2357112 और user2357112 द्वारा मेलिंग सूची में एक टिप्पणी में कहा गया है, odict.values / dict.values एक मल्टीसेट है, सेट का एक सामान्यीकरण जो इसके तत्वों के कई उदाहरणों को अनुमति देता है। तुलना करने की कोशिश करना अंतर्निहित डुप्लिकेशंस के कारण keys या items तुलना keys रूप में तुच्छ नहीं है, ऑर्डरिंग और तथ्य यह है कि आपको शायद उन मानों के अनुरूप कुंजी को ध्यान में रखना होगा। dict_values जो इस तरह दिखना चाहिए:

>>> {1:1, 2:1, 3:2}.values()
dict_values([1, 1, 2])
>>> {1:1, 2:1, 10:2}.values()
dict_values([1, 1, 2])

वास्तव में बराबर हो, भले ही कुंजी के अनुरूप मान समान नहीं हैं? शायद? शायद नहीं? यह किसी भी तरह से सीधे आगे नहीं है और अपरिहार्य भ्रम पैदा करेगा।

हालांकि यह मुद्दा यह है कि मेलिंग सूची पर @abarnett से एक और टिप्पणी के साथ, keys और items साथ तुलना करने के लिए यह तुच्छ नहीं है:

यदि आप सोच रहे हैं कि हम मानक मल्टीसेट प्रकार या उनके लिए एबीसी नहीं होने के बावजूद मल्टीसेट को क्या करना चाहिए, और मूल्य विचारों पर लागू करें, तो अगला प्रश्न यह है कि गैर-हैशबल के लिए वर्गबद्ध समय से बेहतर तरीके से इसे कैसे किया जाए मान। (और आप यहां ऑर्डरिंग नहीं कर सकते हैं, या तो।) 30 सेकंड के लिए मूल्यों को लटकाएंगे और उसके बाद 20 मिलियन में गलत जवाब देने के बजाय इच्छित जवाब के साथ वापस आना चाहिए? (किसी भी तरह से, आप एक ही सबक सीखने जा रहे हैं: मूल्यों के विचारों की तुलना न करें। मैं 20 मिलियन में सीखना चाहता हूं।)





ordereddictionary