पायथन सेट सम्मिलन आदेश को संरक्षित क्यों नहीं करता है?


12

मुझे हाल ही में यह जानकर आश्चर्य हुआ कि जब अजगर को पाइथन 3.7+ में सम्मिलन क्रम को संरक्षित करने की गारंटी दी जाती है, तो सेट नहीं होते हैं:

>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> d
{'a': 1, 'b': 2, 'c': 3}
>>> d['d'] = 4
>>> d
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>> s = {'a', 'b', 'c'}
>>> s
{'b', 'a', 'c'}
>>> s.add('d')
>>> s
{'d', 'b', 'a', 'c'}

इस अंतर के लिए तर्क क्या है? क्या वही दक्षता में सुधार किया गया है जिसके कारण पायथन टीम ने तानाशाही लागू करने के लिए सेट पर भी लागू नहीं किया है?

मैं पॉइंटर्स के लिए ऑर्डर-सेट के कार्यान्वयन या सेट के लिए स्टिक-इन के रूप में उपयोग करने के तरीके की तलाश नहीं कर रहा हूं। मैं बस सोच रहा हूं कि पायथन टीम ने एक ही समय में आदेशों के संरक्षण के लिए बिल्ट-इन सेट क्यों नहीं बनाए।


1
क्या इससे आपके सवाल का जवाब मिलता है? क्या पायथन के पास एक निर्धारित सेट है?
मिहाई चेलारू

1
नहीं, मैं समझता हूं कि पायथन के पास एक निर्मित सेट नहीं है। मैं बस सोच रहा हूं कि ऐसा क्यों है, क्योंकि अब dicts का आदेश दिया गया है।
बार्ट रॉबिन्सन

4
उपयोग पैटर्न अलग-अलग हैं, इसलिए वे विभिन्न उपयोग-मामलों के लिए अनुकूलित हैं। यह एक आम गलतफहमी है कि सेट सिर्फ सीपीथॉन में शून्य मानों के साथ हैं, यह पूरी तरह से गलत है: कार्यान्वयन अलग हैं। यदि आपका प्रश्न बंद नहीं होता है, तो मैं एक विस्तृत उत्तर दे सकता हूं।
विम

1
"उपयोग के पैटर्न अलग-अलग हैं, इसलिए वे विभिन्न उपयोग-मामलों के लिए अनुकूलित हैं।" सवाल का एक अच्छा जवाब इस पर विस्तृत होगा, मुझे लगता है। सवाल यह है कि संबंधित उपयोग के मामलों के लिए दो अलग-अलग दृष्टिकोण इष्टतम क्या बनाते हैं।
कार्ल केनचेल

ध्यान दें कि PyPy दोनों के लिए dictऔर set2.7 के बाद से एक ही ऑर्डर का उपयोग करता है ।
मिस्टरमियागी

जवाबों:


10

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

जबकि दोनों डेटा संरचनाएँ हैश आधारित हैं, यह एक आम गलत धारणा है जो सेट केवल शून्य मान के साथ dicts के रूप में लागू की जाती है। यहां तक कि इससे पहले कि CPython 3.6 में कॉम्पैक्ट dict कार्यान्वयन, सेट और dict कार्यान्वयन पहले से ही छोटे से कोड पुनः प्रयोग के साथ काफ़ी भिन्न है,। उदाहरण के लिए, dicts यादृच्छिक परिवीक्षा का उपयोग करते हैं, लेकिन सेट कैश स्थानीयता में सुधार करने के लिए रैखिक जांच और खुले पते के संयोजन का उपयोग करते हैं। प्रारंभिक रैखिक जांच ( CPython में डिफ़ॉल्ट 9 चरण ) आसन्न कुंजी / हैश जोड़े की एक श्रृंखला की जांच करेगा, हैश टक्कर से निपटने की लागत को कम करके प्रदर्शन में सुधार करेगा - लगातार मेमोरी एक्सेस बिखरे हुए जांच की तुलना में सस्ता है।

सीपीथॉन के सेट कार्यान्वयन को बदलने के लिए सिद्धांत में यह संभव होगा कि वह कॉम्पैक्ट तानाशाह के समान हो, लेकिन व्यवहार में कमियां हैं, और उल्लेखनीय कोर डेवलपर्स इस तरह के बदलाव के विरोध में थे।

सेट अनियंत्रित रहते हैं। (क्यों? उपयोग पैटर्न अलग हैं। इसके अलावा, अलग कार्यान्वयन।)

- गुइडो वैन रोसुम

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

- रेमंड हेटिंगर

इस बारे में विस्तृत चर्चा कि क्या 3.7 के लिए सेट को संक्षिप्त करना है, और इसके बारे में जवाब क्यों दिया गया कि इसके खिलाफ फैसला किया गया था, अजगर-देव मेलिंग सूचियों में पाया जा सकता है।

सारांश में, मुख्य बिंदु यह हैं कि उपयोग के पैटर्न अलग-अलग हैं (सम्मिलन आदेश डिकट्स जैसे ** kwargs उपयोगी है , सेट के लिए कम है), कॉम्पैक्टिंग सेट के लिए अंतरिक्ष की बचत कम महत्वपूर्ण है (क्योंकि केवल कुंजी और हैश सरणी हैं घनीभूत, कुंजियों, हैश और मूल्यों के विपरीत), और सेट में उक्त रैखिक परिवीक्षा अनुकूलन एक कॉम्पैक्ट कार्यान्वयन के साथ असंगत है।

मैं नीचे रेमंड के पद को पुन: पेश करूंगा जिसमें सबसे महत्वपूर्ण बिंदु शामिल हैं।

14 सितंबर, 2016 को 3:50 बजे, एरिक स्नो ने लिखा:

फिर, मैं सेट्स के लिए भी ऐसा ही करूंगा।

जब तक मैंने गलत नहीं समझा, रेमंड सेट करने के लिए समान परिवर्तन करने का विरोध कर रहा था।

ये सही है। इस विषय पर कुछ विचार इस प्रकार हैं कि लोग जंगली दौड़ना शुरू करते हैं।

  • कॉम्पैक्ट तानाशाह के लिए, अंतरिक्ष की बचत सूचकांकों द्वारा खपत अतिरिक्त स्थान के साथ एक शुद्ध जीत थी और कुंजी / मूल्य / हैश सरणियों के बेहतर घनत्व द्वारा ऑफसेट से अधिक होने के लिए कुंजी / मूल्य / हैश सरणियों के लिए समग्र रूप से। हालाँकि सेट्स के लिए, नेट बहुत कम अनुकूल था क्योंकि हमें अभी भी सूचकांकों और समग्रता की आवश्यकता है लेकिन केवल तीन सरणियों में से केवल दो को कम करके अंतरिक्ष लागत को ऑफसेट कर सकते हैं। दूसरे शब्दों में, जब आप कुंजियों, मूल्यों और हैश के लिए जगह बर्बाद कर लेते हैं, तो कॉम्पैक्टिंग अधिक मायने रखती है। यदि आप उन तीनों में से एक को खो देते हैं, तो यह सम्मोहक होना बंद हो जाता है।

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

  • मैंने सेट प्रदर्शन को बेहतर बनाने के लिए वैकल्पिक रास्ता अपनाया। कॉम्पैक्ट करने के बजाय (जो कि अधिक स्थान की जीत नहीं थी और एक अतिरिक्त अप्रत्यक्ष लागत की वजह से), मैंने टकराव की लागत को कम करने और कैश प्रदर्शन में सुधार करने के लिए रैखिक जांच को जोड़ा। यह सुधार शब्दकोशों के लिए वकालत करने वाले दृष्टिकोण के साथ असंगत है।

  • अभी के लिए, शब्दकोशों पर आदेश देने वाला साइड-इफ़ेक्ट नॉन-गारंटीकृत है, इसलिए सेट को जोर देने के साथ-साथ ऑर्डर करना भी शुरू करना समय से पहले है। डॉक्स पहले से ही ऑर्डरडसेट ( https://code.activestate.com/recipes/576694/ ) बनाने के लिए एक रेसिपी से लिंक करता है, लेकिन ऐसा लगता है कि अपटेक लगभग शून्य हो गया है। इसके अलावा, अब जब एरिक स्नो ने हमें एक फास्ट ऑर्डरेड डिक्टेड दिया है, तो मुटेबलसेट और ऑर्डरडीडिक्ट से ऑर्डरडसेट का निर्माण करना पहले से कहीं अधिक आसान है, लेकिन फिर से मैंने कोई वास्तविक रुचि नहीं दिखाई है क्योंकि विशिष्ट सेट-टू-सेट डेटा एनालिटिक्स वास्तव में नहीं है आदेश देने के बारे में जरूरत या देखभाल। इसी तरह, तेजी से सदस्यता परीक्षण का प्राथमिक उपयोग आदेश अज्ञेय है।

  • मैंने कहा, मुझे लगता है कि PyPI में वैकल्पिक सेट कार्यान्वयन को जोड़ने के लिए जगह है। विशेष रूप से, ऑर्डर करने योग्य डेटा के लिए कुछ दिलचस्प विशेष मामले हैं जहां सेट-टू-सेट ऑपरेशन को चाबियों की पूरी श्रृंखला की तुलना करके स्पेड-अप किया जा सकता है (देखें https://code.activestate.com/recipes/230113-implementation-of- एक प्रारंभिक बिंदु के लिए सेट-उपयोग-सॉर्ट किए गए-सूची )। IIRC, PyPI में पहले से ही सेट-जैसे ब्लूम फ़िल्टर और कोयल हैशिंग के लिए कोड है।

  • मैं समझता हूं कि पायथन कोर में स्वीकार किए गए कोड का एक प्रमुख ब्लॉक होना रोमांचक है, लेकिन जब तक कि यह सुनिश्चित नहीं हो जाता है कि हम अन्य डेटाटाइप्स के अधिक प्रमुख रिट्वीट्स में उलझाने के लिए फ्लगगेट्स को नहीं खोल सकते हैं।

- रेमंड हेटिंगर

से [अजगर-देव] अजगर 3.6 dict कॉम्पैक्ट हो जाता है और एक निजी संस्करण हो जाता है; और कीवर्ड ऑर्डर हो गए हैं , सितंबर 2016


2

चर्चाएँ

आपका सवाल जर्मन है और पहले से ही बहुत पहले से ही अजगर-देवों पर बहुत चर्चा की जा चुकी है । आर। हेटिंगर ने उस धागे में तर्कसंगतताओं की एक सूची साझा की । टी। पीटर्स के इस विस्तृत उत्तर के तुरंत बाद इस मुद्दे की स्थिति अब खुलकर सामने आ रही है ।

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


परिप्रेक्ष्य

पायथन में सेट की अनियंत्रित प्रकृति गणितीय सेटों के व्यवहार को समानता देती है । आदेश की गारंटी नहीं है।

इसी गणितीय अवधारणा को अनियंत्रित किया गया है और इस तरह के आदेश - R. Hettinger को लागू करना अजीब होगा

यदि पायथन में सेट करने के लिए किसी भी प्रकार का आदेश दिया गया था, तो यह व्यवहार एक पूरी तरह से अलग गणितीय संरचना का पालन करेगा, अर्थात् एक आदेश सेट (या ओसेट)। ऑसेट्स गणित में एक अलग रोल निभाते हैं, विशेषकर कॉम्बिनेटरिक्स में। ऑसेट्स का एक व्यावहारिक अनुप्रयोग घंटियाँ बदलने में मनाया जाता है ।

बिना सेट किए गए सेट बहुत ही सामान्य और सर्वव्यापी डेटा संरचना के अनुरूप होते हैं जो अधिकांश आधुनिक गणित को सेट करता है , अर्थात सेट थ्योरी । मैं प्रस्तुत करता हूं, पायथन में अनियंत्रित सेट अच्छा है।

इस विषय पर विस्तार से संबंधित पोस्ट भी देखें:

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.