अपने कंस्ट्रक्टर का उपयोग करके एक ऑर्डरडीक को इनिशियलाइज़ करने का सही तरीका है कि यह शुरुआती डेटा के ऑर्डर को बरकरार रखे?


124

एक आदेशित शब्दकोश (OD) को इनिशियलाइज़ करने का सही तरीका क्या है ताकि यह प्रारंभिक डेटा के क्रम को बरकरार रखे?

from collections import OrderedDict

# Obviously wrong because regular dict loses order
d = OrderedDict({'b':2, 'a':1}) 

# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b',2), ('a', 1)])

# What about using a list comprehension, will 'd' preserve the order of 'l'
l = ['b', 'a', 'c', 'aa']
d = OrderedDict([(i,i) for i in l])

सवाल:

  • OrderedDictप्रारंभ के समय उत्तीर्ण (2 और 3 उदाहरण ऊपर) tuples की सूची, या tuples या tuple of tuples या सूचियों की tuple या सूचियों आदि की सूची को संरक्षित करेगा ?

  • यदि OrderedDictवास्तव में कोई आदेश बनाए रखता है, तो सत्यापन के बारे में कैसे जाना जाता है? चूँकि एक dictअप्रत्याशित आदेश दिया गया है, क्या होगा यदि मेरे परीक्षण वैक्टर सौभाग्य से एक प्रारंभिक आदेश एक अप्रत्याशित आदेश के समान है? उदाहरण के लिए, अगर d = OrderedDict({'b':2, 'a':1})मैं लिखने के बजाय d = OrderedDict({'a':1, 'b':2}), मैं गलत तरीके से निष्कर्ष निकाल सकता हूं कि आदेश संरक्षित है। इस मामले में, मुझे पता चला कि एक dictवर्णानुक्रम में क्रमबद्ध है, लेकिन यह हमेशा सच नहीं हो सकता है। यह सत्यापित करने के लिए कि डेटा संरचना ऑर्डर को सुरक्षित रखती है या नहीं, एक बार टूटने तक परीक्षण वैक्टर को बार-बार आज़माने से कम करने के लिए काउंटरटेम्पल का उपयोग करने का एक विश्वसनीय तरीका क्या है?

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

PPS: उम्मीद है, भविष्य में, ऑर्डरडीडक्ट kwargs के ऑर्डर को भी संरक्षित करेगा (उदाहरण 1): http://bugs.python.org/issue16991


10
यह अस्पष्ट रूप से विडंबना है कि एक (गैर-खाली) आदेश के साथ एक ऑर्डरडिक्ट को प्रारंभ करना गलत काम है ... यकीनन इसका परिणाम चेतावनी में होना चाहिए क्योंकि यह संभवतः उपयोगकर्ता के इरादे का उल्लंघन करता है।
2

3
Python3.6 के बाद, OrderDict(b=2, a=1)एक उचित तरीका भी है। पीईपी 468 देखें ।
IvanaGyro

जवाबों:


90

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

ध्यान दें कि आपके पिछले उदाहरण में सूची समझ का उपयोग करने से कुछ भी नहीं बदलता है। वहाँ के बीच कोई अंतर नहीं है OrderedDict([(i,i) for i in l])और OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')])। सूची की समझ का मूल्यांकन किया जाता है और सूची बनाता है और इसे पारित किया जाता है; ऑर्डरडिट को कुछ भी नहीं पता है कि यह कैसे बनाया गया था।


74
# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b', 2), ('a', 1)])

हाँ, वह काम करेगा। परिभाषा के अनुसार, एक सूची को हमेशा उस तरीके का आदेश दिया जाता है जिस तरह से इसका प्रतिनिधित्व किया जाता है। यह लिस्ट-कॉम्प्रिहेंशन के लिए भी जाता है, जेनरेट की गई सूची उसी तरह से है जैसे डेटा प्रदान किया गया था (यानी एक सूची से स्रोत यह नियतात्मक होगा, एक setया dictअधिक से खट्टा होगा )।

यदि OrderedDictवास्तव में एक आदेश बनाए रखा जाता है, तो सत्यापित करने के बारे में कैसे जाना जाता है। चूँकि किसी तानाशाह के पास अप्रत्याशित आदेश होता है, क्या होगा यदि मेरा परीक्षण वैक्टर सौभाग्य से एक प्रारंभिक आदेश के रूप में एक तानाशाह के अप्रत्याशित आदेश का है? उदाहरण के लिए, यदि d = OrderedDict({'b':2, 'a':1})मैं लिखने के बजाय d = OrderedDict({'a':1, 'b':2}), मैं गलत तरीके से निष्कर्ष निकाल सकता हूं कि आदेश संरक्षित है। इस मामले में, मुझे पता चला कि dictवर्णानुक्रम में एक आदेश है, लेकिन यह हमेशा सच नहीं हो सकता है। यदि एक डेटा संरचना ऑर्डर को संरक्षित करती है या एक बार टूटने तक परीक्षण वैक्टर को बार-बार आज़माने के लिए नहीं तो सत्यापित करने के लिए काउंटर उदाहरण का उपयोग करने का एक विश्वसनीय तरीका क्या है।

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


आदेश को सत्यापित करने के बारे में: मैं यह कैसे सुनिश्चित करूं कि मेरा 2-टुपल यह अप्रत्याशित होने पर तानाशाही के क्रम को तोड़ देगा? यह किसी भी डेटा संरचना के बारे में एक सामान्य प्रश्न है, शायद मुझे इसे इस प्रश्न से अलग करना चाहिए।
क्लिक करें

1
आप कुछ ऐसा नहीं कर सकते हैं जो प्रकृति में गैर-नियतात्मक है।
मेटेटास्टर

1
तो ऐसी चीजों का परीक्षण करने का सही तरीका क्या है? आप बस अनिश्चित काल के लिए कोशिश कर रहे हैं? आदेश प्रोग्रामर के लिए अप्रत्याशित है, लेकिन चूंकि यह एक हैश मैप है, इसलिए यह 'कुछ' एल्गोरिथ्म का अनुसरण करता है और एक सही परीक्षण को काउंटर करने की कोशिश करनी चाहिए?
क्लिक करें

2
देख लो __hash__। विशेष रूप से strप्रकार के बारे में ।
मेटेटास्टर

परिभाषा के अनुसार, एक सूची को हमेशा उस तरीके का आदेश दिया जाता है जिस तरह से इसका प्रतिनिधित्व किया जाता है। यह मेरे लिए एक महत्वपूर्ण बयान था। मैंने बस अपने मूल के लिए 2-टुपल्स की एक सूची का उपयोग करने का निर्णय लिया, OrderedDictताकि मेरे पास सूची को परिवर्तित करने का ओवरहेड न हो OrderedDict। मैं सिर्फ एक शब्दकोश के बजाय एक सूची की तरह तत्वों के माध्यम से लूप।
बोबोर्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.