पायथन में, मैं क्रमबद्ध कुंजी क्रम में एक शब्दकोश पर कैसे पुनरावृति करता हूं?


211

एक मौजूदा फ़ंक्शन है जो निम्नलिखित में समाप्त होता है, जहां dएक शब्दकोश है:

return d.iteritems()

जो किसी दिए गए शब्दकोश के लिए एक अपरिवर्तनीय पुनरावृत्ति देता है। मैं एक पुनरावृत्ती लौटना चाहूंगा जो कि कुंजी द्वारा छांटे गए सामानों के माध्यम से जाती है । मैं उसको कैसे करू?

जवाबों:


171

बहुत बड़े पैमाने पर इसका परीक्षण नहीं किया गया, लेकिन यह पायथन 2.5.2 में काम करता है।

>>> d = {"x":2, "h":15, "a":2222}
>>> it = iter(sorted(d.iteritems()))
>>> it.next()
('a', 2222)
>>> it.next()
('h', 15)
>>> it.next()
('x', 2)
>>>

आप करने के लिए उपयोग किया जाता है for key, value in d.iteritems(): ...iterators के बजाय, यह अभी भी ऊपर समाधान के साथ काम करेंगे

>>> d = {"x":2, "h":15, "a":2222}
>>> for key, value in sorted(d.iteritems()):
>>>     print(key, value)
('a', 2222)
('h', 15)
('x', 2)
>>>

पायथन 3.x के साथ, एक पुनरावृत्त को लौटाने के d.items()बजाय उपयोग करें d.iteritems()


29
.items()इसके बजाय का उपयोग करें iteritems(): जैसा कि @Claudiu ने कहा, पुनरावृत्तियाँ पायथन 3.x के लिए काम नहीं करती हैं, लेकिन items()पायथन 2.6 से उपलब्ध है।
रेमी

40
यह स्पष्ट नहीं है। वास्तव में, items()एक सूची बनाता है और इसलिए स्मृति का उपयोग करता है, जबकि iteritems()अनिवार्य रूप से स्मृति का उपयोग नहीं करता है। क्या उपयोग करें ज्यादातर डिक्शनरी के आकार पर निर्भर करता है। इसके अलावा, स्वचालित पायथन 2 से पायथन 3 रूपांतरण उपकरण ( 2to3) स्वचालित रूप से रूपांतरण का ध्यान रखता iteritems()है items(), इसलिए इस बारे में चिंता करने की कोई आवश्यकता नहीं है।
एरिक ओ लेबिगॉट

5
@HowerHell collections.OrderedDictआप एक बार उपयोग करते हैं और एक बार क्रमबद्ध क्रम में आइटम प्राप्त करते हैं।
मार्क हार्विन्स

9
लेकिन @ ईओएल, भले ही iteritems()मेमोरी का उपयोग न करता हो, सब कुछ के लिए मेमोरी में खींच लिया जाना चाहिए sorted(), इसलिए मेमोरी-वार के उपयोग items()और iteritems()यहाँ के बीच कोई अंतर नहीं है ।
रिचर्ड

8
@ रीचर्ड: जबकि यह सच है कि सभी तत्वों को मेमोरी में खींचा जाना चाहिए, वे दो बार (सूची में दी गई सूची में , और सॉर्ट की गई सूची में) और केवल एक बार ( केवल सॉर्ट की गई सूची में) के साथ संग्रहीत होते हैं । items()items()iteritems()
एरिक ओ लेबिगॉट

83

sorted()फ़ंक्शन का उपयोग करें :

return sorted(dict.iteritems())

यदि आप सॉर्ट किए गए परिणामों पर एक वास्तविक पुनरावृत्ति चाहते हैं, क्योंकि sorted()एक सूची देता है, उपयोग करें:

return iter(sorted(dict.iteritems()))

यह मेरे लिए विफल रहता है: <टाइप करें 'अपवाद। टाइप' '>: iter ()' लिस्ट 'के नॉन-इटरेटर को लौटा दिया
माइक

ऐसा शायद इसलिए है क्योंकि आप चर नाम के रूप में "तानाशाही" का उपयोग करते हैं। "तानाशाही" वास्तव में शब्दकोशों का प्रकार है। बस "mydict" जैसे किसी अन्य नाम का उपयोग करें यहां और वोइला।
utku_karatas

1
अभी भी काम नहीं कर रहा है। क्या आप सकारात्मक क्रमबद्ध () एक अन्य पुनरावृत्तिकर्ता को लौटाते हैं, एक नियमित सूची के विपरीत?
माइक

यह अपवाद कब और कहाँ होता है? आप बिना किसी समस्या के सूची में दर्ज कर सकते हैं

1
सहमत, आशा। मुझे नहीं लगता कि मैं कभी भी .next () को कॉल में लंघन लाइनों को छोड़कर सीधे कॉल करता हूं। हमारे iter (सॉर्ट किए गए (dict.iteritems ())) समाधान "सॉर्ट किए गए" (वैसे भी चरण में) मेमोरी में पूरे हुक्म की एक प्रति बनाते हुए समाप्त होता है, इसलिए प्राथमिक

39

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

क्रमबद्ध () हमेशा एक सूची देता है, न कि एक तानाशाह। यदि आप इसे एक तानाशाही () (जो टुपल्स की एक सूची का उत्पादन करते हैं) पास करते हैं, तो यह टुपल्स [(k1, v1), (k2, v2), ...] की एक सूची लौटाएगा जिसका उपयोग लूप में किया जा सकता है। एक तरह से बहुत ज्यादा एक तानाशाह की तरह, लेकिन यह वैसे भी एक तानाशाह में नहीं है !

foo = {
    'a':    1,
    'b':    2,
    'c':    3,
    }

print foo
>>> {'a': 1, 'c': 3, 'b': 2}

print foo.items()
>>> [('a', 1), ('c', 3), ('b', 2)]

print sorted(foo.items())
>>> [('a', 1), ('b', 2), ('c', 3)]

निम्नलिखित एक लूप में एक तानाशाह की तरह लगता है, लेकिन यह नहीं है, यह ट्यूपल्स की एक सूची है जिसे k, v में अनपैक किया जा रहा है:

for k,v in sorted(foo.items()):
    print k, v

इसके बराबर:

for k in sorted(foo.keys()):
    print k, foo[k]

ठीक है, लेकिन मुझे डिक्ट या लिस्ट नहीं चाहिए, मुझे Iterator चाहिए। मैं इसे Iterator होने में कैसे मना करूँ?
माइक

2
sorted(foo.keys())यह समतुल्य के रूप में बेहतर है sorted(foo), क्योंकि शब्दकोशों ने अपनी कुंजियों को वापस कर दिया जब पुनरावृति ( foo.keys()मध्यवर्ती सूची बनाने के लिए मजबूर नहीं होने के लाभ के साथ , शायद- sorted()पुनरावृत्तियों के लिए कैसे लागू किया जाता है पर निर्भर करता है)।
एरिक ओ लेबिगॉट

आश्चर्य जो गति और / या स्मृति के लिए बेहतर है k in sorted(foo.keys()):जो कुंजियों को खींचता है या for k,v in sorted(foo.items()):जो शब्दकोश की सूची जोड़े की एक प्रति लौटाता है मुझे लगता हैsorted(foo.keys())
CrandellWS

1
@CrandellWS: समय प्रश्न का उत्तर देने का सबसे अच्छा तरीका पायथन टाइमिट मॉड्यूल है।
पीटर रोवेल

1
@frank - लघु उत्तर: नहीं। एक ताना वास्तविक कुंजी के साथ एक सरणी है जो आपूर्ति की गई कुंजी के मूल्य का हैश है। यद्यपि कुछ कार्यान्वयन काफी अनुमानित हो सकते हैं, और कुछ भी इस अनुबंध को बना सकते हैं, मैं कुछ भी नहीं गिनता जब यह हैश ऑर्डर करने की बात आती है। 3.6+ व्यवहार पर अधिक के लिए इस पोस्ट को देखें । विशेष रूप से पहले जवाब पर ध्यान दें।
पीटर रोवेल

31

ग्रेग का जवाब सही है। ध्यान दें कि पायथन 3.0 में आपको करना होगा

sorted(dict.items())

के रूप में iteritemsचला जाएगा।


यह मेरे लिए विफल रहता है: <टाइप 'अपवाद। टाइप'रोर'>: iter () प्रकार की गैर-पुनरावृति लौटा 'सूची'
माइक

3
"न ही कारों का उपयोग करें क्योंकि भविष्य में हमारे पास होवरबोर्ड होंगे"
जे जे

7

आप अब OrderedDictपायथन 2.7 में भी उपयोग कर सकते हैं :

>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
...                  ('second', 2),
...                  ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]

यहां आपके पास 2.7 संस्करण और ऑर्डर किए गए API के लिए नया पृष्ठ है


यह कुंजी, उनके द्वारा डाले गए क्रम में मान - एक क्रमबद्ध क्रम में नहीं (यानी अक्षर) में वापस आ जाएगी।
टोनी सफ़ोकल 66

5

सामान्य तौर पर, कोई व्यक्ति एक तानाशाही को सुलझा सकता है:

for k in sorted(d):
    print k, d[k]

प्रश्न में विशिष्ट मामले के लिए, d.iteritems () के लिए "प्रतिस्थापन में गिरावट" होने पर, एक फ़ंक्शन जोड़ें:

def sortdict(d, **opts):
    # **opts so any currently supported sorted() options can be passed
    for k in sorted(d, **opts):
        yield k, d[k]

और इसलिए अंतिम पंक्ति से परिवर्तन होता है

return dict.iteritems()

सेवा

return sortdict(dict)

या

return sortdict(dict, reverse = True)

5
>>> import heapq
>>> d = {"c": 2, "b": 9, "a": 4, "d": 8}
>>> def iter_sorted(d):
        keys = list(d)
        heapq.heapify(keys) # Transforms to heap in O(N) time
        while keys:
            k = heapq.heappop(keys) # takes O(log n) time
            yield (k, d[k])


>>> i = iter_sorted(d)
>>> for x in i:
        print x


('a', 4)
('b', 9)
('c', 2)
('d', 8)

इस पद्धति में अभी भी एक O (N लॉग एन) सॉर्ट है, हालांकि, एक छोटे रैखिक ढेर के बाद, यह सॉर्ट किए गए क्रम में आइटमों की पैदावार करता है क्योंकि यह जाता है, इसे सैद्धांतिक रूप से अधिक कुशल बनाता है जब आपको हमेशा पूरी सूची की आवश्यकता नहीं होती है।


4

यदि आप इस क्रम से क्रमबद्ध करना चाहते हैं कि आइटम कुंजियों के क्रम के बजाय डाले गए हैं, तो आपको पायथन के संग्रह पर एक नज़र रखना चाहिए । (केवल पायथन 3)


3

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

मुझे नहीं पता कि आपके कोड का बड़ा संदर्भ क्या है, लेकिन आप परिणामी सूची में एक पुनरावृत्ति जोड़ने की कोशिश कर सकते हैं। शायद यह पसंद है ?:

return iter(sorted(dict.iteritems()))

निश्चित रूप से अब आपको टुपल्स वापस मिलने लगेंगे क्योंकि आपके सॉर्ट किए गए टुपल्स की सूची में बदल गए हैं

पूर्व: कहते हैं कि आपका तानाशाही था: छंटनी {'a':1,'c':3,'b':2} यह एक सूची में बदल जाता है:

[('a',1),('b',2),('c',3)]

इसलिए जब आप वास्तव में उस सूची पर पुनरावृति करते हैं, जो आपको वापस मिलती है (इस उदाहरण में) एक तार और पूर्णांक से बना एक टपल, लेकिन कम से कम आप इस पर पुनरावृति कर पाएंगे।


2

मान लें कि आप CPython 2.x का उपयोग कर रहे हैं और एक बड़ी डिक्शनरी mydict है, तो सॉर्ट किए गए (mydict) का उपयोग धीमा होने वाला है क्योंकि सॉर्ट किए गए तरीके से mydict की कुंजियों की एक सॉर्ट की गई सूची बनती है।

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

http://anthon.home.xs4all.nl/Python/ordereddict/

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