2008-09-13 11 views
50

क्या पाइथन शब्दकोश से आइटम को पुनर्प्राप्त करने के क्रम में आइटम पुनर्प्राप्त करना संभव है?आप एक शब्दकोष से आइटम को कैसे क्रमबद्ध करते हैं, उसे पुनर्प्राप्त करते हैं?

+0

के संभावित डुप्लिकेट [क्यों शब्दकोश मूल्यों डाला क्रम में नहीं हैं?] (http://stackoverflow.com/questions/6061380/why-dictionary-values-arent-in-the-inserted-order) – nbro

उत्तर

49

मानक पायथन dict ऐसा करने में सक्षम नहीं है।

मानक लाइब्रेरी में collections मॉड्यूल में "आदेशित शब्दकोश" (जो प्रविष्टि के क्रम का ट्रैक रखता है) जोड़ने के लिए एक प्रस्ताव (PEP 372) है। इसमें variousimplementationsofordereddictionaries के लिंक शामिल हैं (पाइथन कुकबुक में इन tworecipes को भी देखें)।

यदि आप चाहते हैं कि आपका कोड "आधिकारिक" संस्करण (यदि प्रस्ताव अंततः स्वीकार किया गया हो) के साथ संगत हो, तो आप पीईपी में संदर्भ कार्यान्वयन के साथ रहना चाहेंगे।

संपादित करें: पीईपी स्वीकार किया गया और पायथन 2.7 और 3.1 में जोड़ा गया। the docs देखें।

6

आप बेस डॉट क्लास के साथ ऐसा नहीं कर सकते - यह हैश द्वारा आदेश दिया गया है। आप अपना खुद का शब्दकोश बना सकते हैं जो वास्तव में कुंजी, मूल्य जोड़े या somesuch की एक सूची है, जिसे आदेश दिया जाएगा।

+2

आपका शब्दकोश कार्यान्वयन इसके बजाय मानक शब्दकोश और एक सूची का उपयोग कर सकता है - शब्दकोश कुंजी-> मूल्य संग्रहीत करता है एसोसिएशन, और सूची में स्टोर स्टोर कुंजी वाई डाला गया है। –

18

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

class ordered_dict(dict): 
    def __init__(self, *args, **kwargs): 
     dict.__init__(self, *args, **kwargs) 
     self._order = self.keys() 

    def __setitem__(self, key, value): 
     dict.__setitem__(self, key, value) 
     if key in self._order: 
      self._order.remove(key) 
     self._order.append(key) 

    def __delitem__(self, key): 
     dict.__delitem__(self, key) 
     self._order.remove(key) 

    def order(self): 
     return self._order[:] 

    def ordered_items(self): 
     return [(key,self[key]) for key in self._order] 


od = ordered_dict() 
od["hello"] = "world" 
od["goodbye"] = "cruel world" 
print od.order()   # prints ['hello', 'goodbye'] 

del od["hello"] 
od["monty"] = "python" 
print od.order()   # prints ['goodbye', 'monty'] 

od["hello"] = "kitty" 
print od.order()   # prints ['goodbye', 'monty', 'hello'] 

print od.ordered_items() 
# prints [('goodbye','cruel world'), ('monty','python'), ('hello','kitty')] 
+0

order_dict (('key_a', 'value_a') है, ('key_b', 'value_b')) सही ढंग से आदेश दिया गया है? ऐसा लगता है कि _order को __init__ में self.keys() पर सेट किया जाएगा, जिसे हैश ऑर्डरिंग में ऑर्डर किया गया है, न कि ऑर्डर दर्ज किया गया था? बस उत्सुक। –

+0

आप सही हैं, यही कारण है कि मैंने कहा, "निर्माता को पास किए गए मूल्यों का क्रम अनिर्धारित है लेकिन बाद में मूल्यों को पारित करने से पहले आएगा"। उनको सही तरीके से आदेश देना संभव होगा, लेकिन मुझे यकीन नहीं था कि यह वांछित व्यवहार था, क्योंकि तर्कसंगत रूप से ऐसी वस्तुओं को एक साथ डाला जाता है। –

0

अगर आप की जरूरत नहीं है dict कार्यक्षमता, और केवल आपके द्वारा डाले गए क्रम में tuples को वापस करने की आवश्यकता है, कतार एक बेहतर काम नहीं करेगा?

7

या, बस time.now() टपल में पहले क्षेत्र के रूप में के साथ कुंजी एक टपल बनाते हैं।

फिर आप dictname.keys(), sort, और voila के साथ कुंजी पुनर्प्राप्त कर सकते हैं!

गेरी

+1

यह आपके द्वारा डाले गए बिल्कुल सही तरीके से जानने के बिना निर्देश में प्रविष्टियों को देखना असंभव बनाता है। यह कुंजी-मूल्य जोड़े की सूची से बेहतर नहीं है। – user2357112

1

यह जब तक आप बाद में संदर्भित करने के लिए एक अलग सूची में कुंजी की दुकान संभव नहीं है।

2

या PEP-372 के लिए कार्यान्वयन से किसी का उपयोग pythonutils से here वर्णित है, odict module की तरह।

मैंने सफलतापूर्वक पोको का उपयोग किया।org कार्यान्वयन, यह आपके साथ

my_dict={} 
my_dict["foo"]="bar" 

my_dict=odict.odict() 
my_dict["foo"]="bar" 

की जगह के रूप में आसान है और आवश्यकता होती है सिर्फ this file

1

आप क्या कर सकते, एक महत्वपूर्ण आदेश inputted का प्रतिनिधित्व करने के साथ मूल्यों सम्मिलित है और फिर आइटम पर sorted() पर कॉल करें।

>>> obj = {} 
>>> obj[1] = 'Bob' 
>>> obj[2] = 'Sally' 
>>> obj[3] = 'Joe' 
>>> for k, v in sorted(obj.items()): 
...  print v 
... 
Bob 
Sally 
Joe 
>>> 
+1

अगर हमें अन्य उद्देश्यों के लिए पहले से ही कुंजी की आवश्यकता नहीं है, तो हम एक सूची का उपयोग करेंगे। यह कुछ भी नहीं करता है एक सूची बेहतर नहीं करता है। – user2357112

+1

@ user2357112, हालांकि, यह ** करने के लिए एक और तरीका व्यक्त करता है ** ओपी ने क्या पूछा **। ओपी ने उन आदेशों को मुद्रित करने के तरीके से नहीं पूछा था, ओपी ने कहा था कि वस्तुओं को मुद्रित करने के लिए ** 'dict' ** में कैसे प्रिंट करें। बड़ा अंतर। –

+0

आपने मूल उद्देश्य के लिए इसे अनुपयोगी बनाने के बिंदु पर dict के प्रारूप को बदल दिया है। यदि मूल रूप से मूल रूप से संबद्ध था, तो कहें, फोन नंबरों के नाम, आपको लगातार पुनरावृत्ति आदेश प्राप्त हुआ है, लेकिन आपको पता नहीं है कि बॉब का फ़ोन नंबर क्या है। – user2357112

6

उपयोग OrderedDict(), संस्करण 2.7

जिज्ञासा की बस एक बात के बाद से उपलब्ध:

from collections import OrderedDict 
a = {} 
b = OrderedDict() 
c = OredredDict() 

a['key1'] = 'value1' 
a['key2'] = 'value2' 

b['key1'] = 'value1' 
b['key2'] = 'value2' 

c['key2'] = 'value2' 
c['key1'] = 'value1' 

print a == b #True 
print a == C#True 
print b == C#False 
संबंधित मुद्दे