'छोरों' के लिए 'का उपयोग करते हुए शब्दकोशों पर फेरबदल


3134

मैं निम्नलिखित कोड से थोड़ा हैरान हूँ:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    print key, 'corresponds to', d[key]

जो मुझे समझ में नहीं आता वह keyहिस्सा है। पायथन कैसे पहचानता है कि इसे केवल शब्दकोश से कुंजी पढ़ने की आवश्यकता है? है keyपायथन में एक विशेष शब्द? या यह केवल एक चर है?


3
नया उत्तर पोस्ट करने से पहले, विचार करें कि इस प्रश्न के लिए पहले से ही 10+ उत्तर हैं। कृपया, सुनिश्चित करें कि आपका उत्तर उन सूचनाओं का योगदान करता है जो मौजूदा उत्तरों में नहीं हैं।
janniks

जवाबों:


5386

key सिर्फ एक चर नाम है।

for key in d:

केवल चाबियाँ और मूल्यों के बजाय शब्दकोश में कुंजियों पर लूप करेंगे। कुंजी और मूल्य दोनों पर लूप करने के लिए आप निम्नलिखित का उपयोग कर सकते हैं:

पायथन 3.x के लिए:

for key, value in d.items():

अजगर के लिए 2.x:

for key, value in d.iteritems():

खुद के लिए परीक्षण करने के लिए, शब्द keyको बदल दें poop

पायथन 3.x में, iteritems()बस के साथ प्रतिस्थापित किया गया था items(), जो कि तानाशाह द्वारा समर्थित एक सेट-जैसे दृश्य देता है, iteritems()लेकिन इससे भी बेहतर। यह भी 2.7 के रूप में उपलब्ध है viewitems()

ऑपरेशन items()2 और 3 दोनों के लिए काम करेगा, लेकिन 2 में यह शब्दकोश के (key, value)जोड़े की एक सूची लौटाएगा , जो कि items()कॉल के बाद होने वाले तानाशाह के परिवर्तनों को प्रतिबिंबित नहीं करेगा । यदि आप 3.x में 2.x व्यवहार चाहते हैं, तो आप कॉल कर सकते हैं list(d.items())


157
इस तरह से मूल्य का उपयोग नहीं करने के लिए एक अनदेखी कारण को जोड़ना: डी के लिए [कुंजी] लूप के अंदर कुंजी फिर से हैश होने का कारण बनता है (मूल्य प्राप्त करने के लिए)। जब शब्दकोश बड़ा होगा तो यह अतिरिक्त हैश समग्र समय में जुड़ जाएगा। इसकी चर्चा रेमंड
हेटिंगर

27
यह उल्लेख करने के लिए समझ में आता है कि वस्तुओं को अप्रत्याशित क्रम में पुनरावृत्त किया जाएगा और sortedइसे स्थिर करने की आवश्यकता है।
प्रात: ९

5
@ हरिशंकरकृष्णस्वामी क्या विकल्प है?
JoeyC

3
@ युगर आप ऐसा क्यों कहते हैं? डॉक्स कहते हैं Keys and values are iterated over in insertion order. [ docs.python.org/3/library/…
Geza Turi

4
@ युगर पायथॉन 3.7 से, शब्दकोश सम्मिलन-आदेशित हैं और यह एक भाषा की विशेषता है। देखें stackoverflow.com/a/39980744/9428564
Aimery

432

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

शब्दकोशों के मामले में, इसे C स्तर पर लागू किया गया है। विवरण पीईपी 234 में उपलब्ध हैं । विशेष रूप से, "डिक्शनरी इटरेटर्स" शीर्षक से:

  • डिक्शनरी एक tp_iter स्लॉट लागू करती है जो एक कुशल पुनरावृत्ति देता है जो डिक्शनरी की कुंजियों पर निर्भर करता है। [...] इसका मतलब है कि हम लिख सकते हैं

    for k in dict: ...

    जो बराबर है, लेकिन उससे कहीं ज्यादा तेज है

    for k in dict.keys(): ...

    जब तक शब्दकोश में संशोधन पर प्रतिबंध (या तो लूप या किसी अन्य धागे द्वारा) का उल्लंघन नहीं किया जाता है।

  • विभिन्न प्रकार के पुनरावृत्तियों को स्पष्ट रूप से वापस लाने वाले शब्दकोशों में विधियाँ जोड़ें:

    for key in dict.iterkeys(): ...
    
    for value in dict.itervalues(): ...
    
    for key, value in dict.iteritems(): ...
    

    इसका मतलब है कि के for x in dictलिए आशुलिपि है for x in dict.iterkeys()

पायथन 3 में dict.iterkeys(), dict.itervalues()और dict.iteritems()अब समर्थित नहीं हैं। उपयोग करें dict.keys(), dict.values()और dict.items()इसके बजाय।


207

dictजैसा कि आप यहाँ देख सकते हैं, बिना किसी विशेष क्रम में इसकी कुंजियों के माध्यम से पुनरावृति पर :

संपादित करें: (यह अब Python3.6 में मामला नहीं है , लेकिन ध्यान दें कि यह अभी तक व्यवहार की गारंटी नहीं है)

>>> d = {'x': 1, 'y': 2, 'z': 3} 
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']

आपके उदाहरण के लिए, यह उपयोग करने के लिए एक बेहतर विचार है dict.items():

>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]

यह आपको ट्यूपल्स की एक सूची देता है। जब आप इस तरह से उन्हें अधिक पाश, प्रत्येक टपल में पैक है kऔर vस्वचालित रूप से:

for k,v in d.items():
    print(k, 'corresponds to', v)

यदि लूप का शरीर केवल कुछ पंक्तियों का है, तो एक से अधिक लूपिंग का उपयोग करना kऔर vचर नामों के रूप dictमें काफी सामान्य है। अधिक जटिल छोरों के लिए अधिक वर्णनात्मक नामों का उपयोग करना एक अच्छा विचार हो सकता है:

for letter, number in d.items():
    print(letter, 'corresponds to', number)

प्रारूप स्ट्रिंग का उपयोग करने की आदत में आना एक अच्छा विचार है:

for letter, number in d.items():
    print('{0} corresponds to {1}'.format(letter, number))

11
पायथन 3.7 के रिलीज़ नोटों से: "प्रमुख वस्तुओं का सम्मिलन-क्रम संरक्षण प्रकृति अब पायथन भाषा की कल्पना का एक आधिकारिक हिस्सा है।"
ग्रेगरी एरेनीस

86

key बस एक चर है।

के लिए Python2.X :

d = {'x': 1, 'y': 2, 'z': 3} 
for my_var in d:
    print my_var, 'corresponds to', d[my_var]

... या और अच्छा,

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.iteritems():
    print the_key, 'corresponds to', the_value

के लिए Python3.X :

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.items():
    print(the_key, 'corresponds to', the_value)

62

जब आप for .. in ..-syntax का उपयोग करके शब्दकोशों के माध्यम से पुनरावृति करते हैं , तो यह हमेशा कुंजियों पर निर्भर करता है (मानों का उपयोग करके पहुंच योग्य है dictionary[key])।

पायथन 2 के उपयोग for k,v in s.iteritems()में और पायथन 3 में, कुंजी-मूल्य वाले जोड़े पर पुनरावृति करने के लिए for k,v in s.items()


38
ध्यान दें कि पायथन 3 के लिए, इसके items()बजायiteritems()
एंड्रियास फॉस्टर

32

यह एक बहुत ही सामान्य लूपिंग मुहावरा है। inएक ऑपरेटर है। कब for key in dictऔर कब उपयोग करना है for key in dict.keys()इसके लिए डेविड गुडगर का मुहावरेदार पायथन लेख (संग्रहीत प्रति) देखना चाहिए ।


जैसा कि मैंने इन वर्गों के बारे में पढ़ा है in, ऑपरेटर भाग वह है जहाँ आप अस्तित्व की जाँच करते हैं । शायद बेहतर इस in is an operatorजानकारी को हटा दें ।
वुल्फ

19

'छोरों' के लिए 'का उपयोग करते हुए शब्दकोशों पर फेरबदल

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    ...

पायथन कैसे पहचानता है कि इसे केवल शब्दकोश से कुंजी पढ़ने की आवश्यकता है? क्या पायथन में एक विशेष शब्द है? या यह केवल एक चर है?

यह सिर्फ forलूप नहीं है। यहाँ महत्वपूर्ण शब्द "पुनरावृति" है।

एक शब्द मूल्यों की कुंजी का मानचित्रण है:

d = {'x': 1, 'y': 2, 'z': 3} 

किसी भी समय हम इस पर पुनरावृत्ति करते हैं, हम कुंजियों पर पुनरावृति करते हैं। चर नाम keyकेवल वर्णनात्मक होने का इरादा है - और यह उद्देश्य के लिए काफी उपयुक्त है।

यह एक सूची समझ में आता है:

>>> [k for k in d]
['x', 'y', 'z']

ऐसा तब होता है जब हम डिक्शनरी (या किसी अन्य संग्रह प्रकार ऑब्जेक्ट) के लिए शब्दकोश पास करते हैं:

>>> list(d)
['x', 'y', 'z']

जिस तरह से पायथन पुनरावृत्त करता है, एक संदर्भ में जहां उसे इसकी आवश्यकता होती है, वह __iter__वस्तु की विधि को बुलाता है (इस मामले में शब्दकोश) जो एक पुनरावृत्त लौटाता है (इस मामले में, एक मुख्य वस्तु):

>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>

हमें इन विशेष विधियों का उपयोग स्वयं नहीं करना चाहिए, इसके बजाय, इसे कॉल करने के लिए संबंधित अंतर्निहित फ़ंक्शन का उपयोग करें iter:

>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>

Iterators में एक __next__विधि है - लेकिन हम इसे बेसिन फ़ंक्शन के साथ कहते हैं next:

>>> next(key_iterator)
'x'
>>> next(key_iterator)
'y'
>>> next(key_iterator)
'z'
>>> next(key_iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

जब एक इटरेटर समाप्त हो जाता है, तो यह बढ़ जाता है StopIteration। यह कैसे पायथन एक forपाश से बाहर निकलने के लिए जानता है , या एक सूची समझ, या एक जनरेटर अभिव्यक्ति, या किसी अन्य पुनरावृत्त संदर्भ। एक बार जब एक StopIterationपुनरावृत्ति उठाता है तो यह हमेशा इसे बढ़ाएगा - यदि आप फिर से पुनरावृति करना चाहते हैं, तो आपको एक नया चाहिए।

>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']

डाइक्ट्स में लौटते हुए

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

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:

यदि हम परिवर्तनशील नाम को बदलते हैं, तो हम अभी भी कुंजी प्राप्त करते हैं। चलो यह कोशिश करते हैं:

>>> for each_key in d:
...     print(each_key, '=>', d[each_key])
... 
x => 1
y => 2
z => 3

यदि हम मूल्यों पर पुनरावृत्ति करना चाहते हैं, तो हमें .valuesdicts की विधि का उपयोग करने की आवश्यकता है , या दोनों के लिए एक साथ .items:

>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]

दिए गए उदाहरण में, इस तरह की वस्तुओं पर पुनरावृति करना अधिक कुशल होगा:

for a_key, corresponding_value in d.items():
    print(a_key, corresponding_value)

लेकिन अकादमिक उद्देश्यों के लिए, प्रश्न का उदाहरण ठीक है।


17

मेरे पास एक उपयोग का मामला है जहां मुझे कुंजी, मूल्य जोड़ी पाने के लिए तानाशाही के माध्यम से पुनरावृति करना है, यह भी सूचकांक का संकेत है कि मैं कहां हूं। यह मेरा इसे करने का तरीका है:

d = {'x': 1, 'y': 2, 'z': 3} 
for i, (key, value) in enumerate(d.items()):
   print(i, key, value)

ध्यान दें कि कुंजी के चारों ओर कोष्ठक, मान महत्वपूर्ण है, बिना कोष्ठक के, आपको एक मान प्राप्त होता है "अनपैक करने के लिए पर्याप्त मान नहीं"।


1
यह सवाल कैसे प्रासंगिक है?
jorijnsmit


4

चाबियों पर पुनरावृति करने के लिए, यह धीमा है लेकिन उपयोग करने के लिए बेहतर है my_dict.keys()। यदि आपने ऐसा कुछ करने की कोशिश की:

for key in my_dict:
    my_dict[key+"-1"] = my_dict[key]-1

यह रनटाइम त्रुटि पैदा करेगा क्योंकि आप प्रोग्राम को चलाते समय कुंजियों को बदल रहे हैं। यदि आप समय को कम करने के लिए बिल्कुल तैयार हैं, तो for key in my_dictरास्ते का उपयोग करें , लेकिन आपको चेतावनी दी गई है;)।


2

यह आउटपुट को क्रमबद्ध क्रम में मानों को आरोही क्रम में प्रिंट करेगा।

d = {'x': 3, 'y': 1, 'z': 2}
def by_value(item):
    return item[1]

for key, value in sorted(d.items(), key=by_value):
    print(key, '->', value)

आउटपुट:

यहां छवि विवरण दर्ज करें

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