घोषित किए गए क्रम में कुंजियाँ / मान कैसे रखें?


320

मेरे पास एक शब्दकोश है जिसे मैंने एक विशेष क्रम में घोषित किया है और इसे हर समय उसी क्रम में रखना चाहता हूं। कुंजियों / मूल्यों को वास्तव में उनके मूल्य के आधार पर क्रम में नहीं रखा जा सकता है, मैं इसे केवल उस क्रम में चाहता हूं जिसे मैंने घोषित किया था।

तो अगर मेरे पास शब्दकोश है:

d = {'ac': 33, 'gw': 20, 'ap': 102, 'za': 321, 'bs': 10}

यह उस क्रम में नहीं है यदि मैं इसे देखता हूं या इसके माध्यम से पुनरावृति करता हूं, तो क्या यह सुनिश्चित करने का कोई तरीका है कि पायथन ने स्पष्ट आदेश को रखा होगा जिसे मैंने कुंजी / मान घोषित किया था?

जवाबों:


229

पायथन 3.6 के बाद से, मानक dictप्रकार डिफ़ॉल्ट रूप से प्रविष्टि क्रम बनाए रखता है।

परिभाषित

d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}

स्रोत कोड में सूचीबद्ध क्रम में कुंजियों के साथ एक शब्दकोश में परिणाम होगा।

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

3.6 में यह अभी भी एक कार्यान्वयन विस्तार माना जाता था; पायथन 3.6 प्रलेखन में नया क्या है देखें :

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

पायथन 3.7 इस कार्यान्वयन विस्तार को एक भाषा विनिर्देश में बढ़ाता है , इसलिए अब यह अनिवार्य है कि dictउस संस्करण या नए के साथ संगत सभी पायथन कार्यान्वयन में आदेश को संरक्षित करता है। BDFL द्वारा उच्चारण देखें ।

आप अभी भी कुछ मामलों में collections.OrderedDict()कक्षा का उपयोग करना चाह सकते हैं , क्योंकि यह मानक dictप्रकार के शीर्ष पर कुछ अतिरिक्त कार्यक्षमता प्रदान करता है । जैसे कि प्रतिवर्ती होने के नाते (यह दृश्य वस्तुओं तक फैली हुई है ), और पुन: समर्थन ( move_to_end()विधि के माध्यम से )।


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

8
@ naught101: नहीं, यह है dict निर्माण के लिए लागू होते हैं। पायथन 3.7 और अप में, एक स्पष्ट प्रदर्शन का उपयोग करते हुए जैसा कि प्रश्न में दिखाया गया है, क्रम में उन कुंजियों को सूचीबद्ध करने की गारंटी है । लिखे गए कुंजी-मूल्य जोड़े को बाएं से दाएं में डाला जाता है, क्योंकि भाषा की युक्ति इस बात की गारंटी देती है : यदि कुंजी / डेटम जोड़े के अल्पविराम से अलग अनुक्रम दिया गया है, तो उन्हें शब्दकोश की प्रविष्टियों को परिभाषित करने के लिए बाएं से दाएं का मूल्यांकन किया जाता हैdict()प्रलेखन भी एक उदाहरण भी शामिल है।
मार्टिन पीटर्स

175
from collections import OrderedDict
OrderedDict((word, True) for word in words)

शामिल

OrderedDict([('He', True), ('will', True), ('be', True), ('the', True), ('winner', True)])

यदि मान हैं True(या कोई अन्य अपरिवर्तनीय वस्तु), तो आप भी उपयोग कर सकते हैं:

OrderedDict.fromkeys(words, True)

2
वर्थ नोटिंग, ज़ाहिर है, कि 'अपरिवर्तनीय' हिस्सा एक कठिन और तेज़ नियम नहीं है जिसे पायथन लागू करेगा - इसका "केवल" एक अच्छा विचार है।
पीवीसी

11
पता है कि जैसे समाधान: OrderedDict(FUTURE=[], TODAY=[], PAST=[])काम नहीं करेगा, जब aproach का उल्लेख किया OrderedDict([('FUTURE', []), ('TODAY', []), ('PAST', [])])जाएगा : आदेश रखेंगे।
औरिलाबस

2
@ कंडी मुझे एक और समस्या है, जब jsonify का उपयोग करते हुए, ऑर्डरडीडक्ट लगता है कि इसे खो दिया गया है जब यह json डेटा उत्पन्न करता है। इसे हल करने के लिए कोई रास्ता नहीं है?
त्यान

github.com/pallets/flask/issues/974 इस समस्या को हल करने के लिए इस्तेमाल किया जा सकता है ..
tyan

5
Python3.7 ने अब डिफ़ॉल्ट रूप से आदेश दिया है। mail.python.org/pipermail/python-dev/2017-Deuled/151283.html
sertsedat

167

सैद्धांतिक भाग की व्याख्या करने के बजाय, मैं एक सरल उदाहरण दूंगा।

>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary['foo']=3
>>> my_dictionary['aol']=1
>>> my_dictionary
OrderedDict([('foo', 3), ('aol', 1)])
>>> dict(my_dictionary)
{'foo': 3, 'aol': 1}

16
क्या डिस टाइप की तरह ऑर्डरडेड को मास असाइन करने का कोई तरीका है?
tyan

2
OrderedDictवास्तव में समस्या को हल करता है, लेकिन ... इस विशेष उदाहरण में आपको एक मानक शब्दकोश का उपयोग करने का बिल्कुल समान परिणाम मिलता है
टोनचैस

2
@ टोनेशे: मैंने सिर्फ एक मानक शब्दकोश के साथ उदाहरण की कोशिश की, और {'aol': 1, 'foo': 3}मुझे ऐसा लगा कि यह एक अच्छा उदाहरण है।
ट्वैसब्रिलिग

4
हर किसी के लिए एक सबक है: यह पता चला था (मुझे लगता है कि 2.4 रिलीज के आसपास) कि पायथन की उम्मीद के मुताबिक हैशिंग सुरक्षा कमजोरियों को जन्म दे सकती है , इसलिए अब कोई गारंटी नहीं है कि एक ही कोड के दो अलग-अलग रन एक मानक में एक ही आदेश देंगे dict।
होल्डनवेब

1
@tyan आप OrderedDict.update()कुंजी-मूल्य वाले जोड़े के साथ चलने योग्य कह सकते हैं d1.upate([(key1, val1), (key2, val2)]):।
रूड अलथुइज़न

37

ध्यान दें कि यह उत्तर python3.7 से पहले अजगर संस्करणों पर लागू होता है। CPython 3.6 कार्यान्वयन के विवरण के रूप में अधिकांश परिस्थितियों में प्रविष्टि क्रम को बनाए रखता है। पायथन 3.7 से शुरू होने के बाद, यह घोषित किया गया है कि कार्यान्वयन अनिवार्य रूप से सम्मिलित होने के आदेश को बनाए रखना चाहिए।


अजगर शब्दकोश अनियंत्रित हैं। यदि आप एक आदेशित शब्दकोश चाहते हैं, तो संग्रह की कोशिश करें । संपादित करें

ध्यान दें कि ऑर्डरडीड को पायथन 2.7 में मानक पुस्तकालय में पेश किया गया था। यदि आपके पास अजगर का पुराना संस्करण है, तो आप ActiveState पर ऑर्डर किए गए शब्दकोशों के लिए व्यंजनों को पा सकते हैं ।


देखें @ मार्टिज़न की पोस्ट ऊपर। अजगर 3.6 से बाद में, डिक्टेशन ऑर्डर करने का समर्थन करता है।
tpk

13

शब्दकोश एक आदेश का उपयोग करेगा जो खोज को कुशल बनाता है, और आप उसे बदल नहीं सकते,

आप बस वस्तुओं की एक सूची (एक साधारण मामले में एक 2 तत्व टपल, या यहां तक ​​कि एक वर्ग) का उपयोग कर सकते हैं, और अंत में आइटम संलग्न कर सकते हैं। फिर आप इसमें आइटम खोजने के लिए रैखिक खोज का उपयोग कर सकते हैं।

वैकल्पिक रूप से आप ऑर्डर बनाए रखने के इरादे से बनाई गई एक अलग डेटा संरचना का निर्माण या उपयोग कर सकते हैं।


शब्दकोश एक आदेश का उपयोग करेगा जो खोज को कुशल बनाता है अंत में, किसी ने इसे इंगित किया।
0/20

7

मुझे इस पोस्ट के दौरान यह पता लगाने की कोशिश की गई कि कैसे काम करने के लिए ऑर्डरडिट प्राप्त किया जाए। ग्रहण के लिए PyDev ऑर्डरडीडक्ट को बिल्कुल भी नहीं मिला, इसलिए मैंने अपने शब्दकोश के प्रमुख मूल्यों का एक हिस्सा बनाने का फैसला किया क्योंकि मैं उन्हें आदेश देना चाहूंगा। जब मुझे अपनी सूची को आउटपुट करने की आवश्यकता हुई, तो मैंने केवल टपल के मूल्यों के माध्यम से पुनरावृत्त किया और टपल से पुनरावृत्त 'कुंजी' को अपने मूल्यों को पुनः प्राप्त करने के लिए शब्दकोश में प्लग इन किया।

उदाहरण:

test_dict = dict( val1 = "hi", val2 = "bye", val3 = "huh?", val4 = "what....")
test_tuple = ( 'val1', 'val2', 'val3', 'val4')
for key in test_tuple: print(test_dict[key])

यह एक अजीब बोझ है, लेकिन मैं समय के लिए दबाया जाता हूं और यह मेरे साथ आया काम है।

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


महान समाधान। मैं इसे जसन को फ़ाइल करने के लिए लिखने के लिए उपयोग करूंगा, हमेशा उसी क्रम में।
हिरोविज टी

6

आप वास्तव में वह नहीं कर सकते जो आप एक शब्दकोश के साथ चाहते हैं। आपके पास पहले से ही डिक्शनरी d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}है। मैंने पाया कि पहले से ही निर्मित होने के बाद इसे क्रम में रखने का कोई तरीका नहीं था। मैंने जो किया वह वस्तु के बजाय एक json फाइल बना रहा था:

{"ac":33,"gw":20,"ap":102,"za":321,"bs":10}

मैंनें इस्तेमाल किया:

r = json.load(open('file.json'), object_pairs_hook=OrderedDict)

तब इस्तेमाल किया:

print json.dumps(r)

जांचना।


1
तो क्यों नहीं एक सूची से एक आदेश के साथ शुरू करें? JSON फ़ाइल वास्तव में यहां कुछ भी नहीं जोड़ती है।
मार्टिन पीटर्स

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

1
लेकिन वह हिस्सा पहले से ही बहुत पुराना जवाब से आच्छादित है, 2012 से किए गए
मार्टिन पीटर्स

3
from collections import OrderedDict
list1 = ['k1', 'k2']
list2 = ['v1', 'v2']
new_ordered_dict = OrderedDict(zip(list1, list2))
print new_ordered_dict
# OrderedDict([('k1', 'v1'), ('k2', 'v2')])

मुख्य समस्या जो किसी भी अधिक स्पष्ट नहीं है, यह ट्यूपल्स की एक सूची है
ओलेग

2

एक अन्य विकल्प पंडों का उपयोग करना है dataframeक्योंकि यह एक आदेश जैसी संरचना में वस्तुओं के आदेश और सूचकांक स्थानों की गारंटी देता है।


1

आमतौर पर, आप एक वर्ग डिज़ाइन कर सकते हैं कि एक शब्दकोश की तरह बर्ताव करती है, मुख्य रूप से तरीकों को लागू करने हो __contains__, __getitem__, __delitem__, __setitem__और कुछ और। उस वर्ग का कोई भी व्यवहार हो सकता है जिसे आप पसंद करते हैं, उदाहरण के लिए कुंजियों पर एक सॉर्ट किए गए पुनरावृत्ति को निजीकृत करना ...


1

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

>>> list =[[1,2],[2,3]]
>>> for i in list:
...     print i[0]
...     print i[1]

1
2
2
3

7
यह एक "शब्दकोश" नहीं है क्योंकि आप पूरे संग्रह (ओ (एन) समय लेने) के बिना खोज के बिना उनकी कुंजी द्वारा आइटम नहीं देख सकते हैं।
BHSPitMonkey

1
हां, यह एक शब्दकोश नहीं है, लेकिन, स्थिति के आधार पर, यह मूल पोस्टर की समस्या का एक वैध समाधान प्रदान कर सकता है।
सनस्पार्क

उन्होंने ठीक नहीं कहा कि हम कैसे चाहते हैं, बस उन्हें आदेश देने में सक्षम होना चाहिए =), क्योंकि हमेशा एक चीज करने के लिए बहुत सारे तरीके होते हैं।
पेलोस

1

मुझे एक ऐसी ही समस्या थी जब एक Django परियोजना को विकसित करना। मैं ऑर्डरडीडिक्ट का उपयोग नहीं कर सकता, क्योंकि मैं अजगर का एक पुराना संस्करण चला रहा था, इसलिए इसका समाधान Django के सॉर्टेडडिक्ट क्लास का उपयोग करना था:

https://code.djangoproject.com/wiki/SortedDict

जैसे,

from django.utils.datastructures import SortedDict
d2 = SortedDict()
d2['b'] = 1
d2['a'] = 2
d2['c'] = 3

नोट: यह उत्तर मूल रूप से 2011 से है। यदि आपके पास पायथन संस्करण 2.7 या उच्चतर तक पहुंच है, तो आपको अब मानक तक पहुंच होनी चाहिए collections.OrderedDict, जिनमें से कई उदाहरण इस धागे में दूसरों द्वारा प्रदान किए गए हैं।


0

आप वही कर सकते हैं जो मैंने शब्दकोश के लिए किया था।

एक सूची बनाएं और खाली शब्दकोश दें:

dictionary_items = {}
fields = [['Name', 'Himanshu Kanojiya'], ['email id', 'hima@gmail.com']]
l = fields[0][0]
m = fields[0][1]
n = fields[1][0]
q = fields[1][1]
dictionary_items[l] = m
dictionary_items[n] = q
print dictionary_items
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.