python - 'For' loops का उपयोग करके शब्दकोशों पर इटरेट करना
python-2.7 dictionary (8)
'For' loops का उपयोग करके शब्दकोशों पर इटरेट करना
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>
हमें इन विशेष तरीकों का उपयोग स्वयं नहीं करना चाहिए, इसके बजाय, इसे कॉल करने के लिए संबंधित बिल्टिन फ़ंक्शन का उपयोग करें, इसे:
>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>
Iterators के पास __next__
विधि है - लेकिन हम इसे __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
बढ़ाता है। इस प्रकार पाइथन लूप, या एक सूची समझ, या जनरेटर अभिव्यक्ति, या किसी अन्य पुनरावृत्ति संदर्भ से बाहर निकलने के लिए जानता है। एक बार जब 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
यदि हम मूल्यों पर .items
: .items
करना चाहते हैं, तो हमें dicts की .values
विधि, या दोनों के लिए एक साथ उपयोग करने की आवश्यकता है .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)
लेकिन अकादमिक उद्देश्यों के लिए, प्रश्न का उदाहरण ठीक है।
मैं निम्नलिखित कोड से थोड़ा परेशान हूं:
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
print key, 'corresponds to', d[key]
जो मुझे समझ में नहीं आता वह key
हिस्सा है। पाइथन कैसे पहचानता है कि इसे केवल शब्दकोश से कुंजी पढ़ने की आवश्यकता है? पाइथन में एक विशेष शब्द key
है? या यह बस एक चर है?
आप dicttype
पर dicttype
के dicttype
के कार्यान्वयन की जांच कर सकते हैं। यह विधि का हस्ताक्षर है जो dict Iterator लागू करता है:
_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
PyObject **pvalue, Py_hash_t *phash)
किसी भी आदेश पर अपनी चाबियों के माध्यम से किसी भी विशेष क्रम में इटरेट करना, जैसा कि आप यहां देख सकते हैं:
संपादित करें: (यह अब 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)]
यह आपको tuples की एक सूची देता है। जब आप उन्हें इस तरह लूप करते हैं, तो प्रत्येक ट्यूपल को स्वचालित रूप से के और v
में अनपॅक किया जाता है:
for k,v in d.items():
print(k, 'corresponds to', v)
लूप का शरीर केवल कुछ पंक्तियों पर एक dict
पर लूपिंग करते समय परिवर्तनीय नाम के रूप में के और v
का उपयोग करना आम है। अधिक जटिल लूप के लिए अधिक वर्णनात्मक नामों का उपयोग करना एक अच्छा विचार हो सकता है:
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))
चाबियों को फिर से my_dict.keys()
करने के लिए, यह धीमा है लेकिन my_dict.keys()
का उपयोग करने के लिए बेहतर है। यदि आपने ऐसा कुछ करने की कोशिश की है:
for key in my_dict:
my_dict[key+"-1"] = my_dict[key]-1
यह रनटाइम त्रुटि उत्पन्न करेगा क्योंकि प्रोग्राम चल रहा है, जबकि आप कुंजी बदल रहे हैं। यदि आप पूरी तरह से समय कम करने पर सेट हैं, तो for key in my_dict
तरीके से for key in my_dict
के for key in my_dict
उपयोग करें, लेकिन आपको चेतावनी दी गई है;)।
मेरे पास एक उपयोग का मामला है जहां मुझे कुंजी, मूल्य जोड़ी प्राप्त करने के लिए निर्देश के माध्यम से पुनरावृत्ति करना है, यह सूचकांक भी इंगित करता है कि मैं कहां हूं। यह मेरा इसे करने का तरीका है:
d = {'x': 1, 'y': 2, 'z': 3}
for i, (key, value) in enumerate(d.items()):
print(i, key, value)
ध्यान दें कि कुंजी के चारों ओर कोष्ठक, मूल्य कोष्ठक के बिना महत्वपूर्ण है, आपको एक ValueError "अनपॅक करने के लिए पर्याप्त मान नहीं" मिलता है।
यह एक बहुत आम लूपिंग मुहावरे है। in
एक ऑपरेटर है। जब for key in dict
लिए उपयोग करना है और जब यह for key in dict.keys()
होना चाहिए for key in dict.keys()
डेविड for key in dict.keys()
पायथन लेख देखें ।
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)
key
सिर्फ एक चर नाम है।
for key in d:
कुंजियों और मूल्यों के बजाए, शब्दकोश में कुंजी पर बस लूप होगा। दोनों कुंजी और मूल्य पर लूप करने के लिए आप निम्न का उपयोग कर सकते हैं:
पायथन 2.x के लिए:
for key, value in d.iteritems():
पायथन 3.x के लिए:
for key, value in d.items():
अपने लिए परीक्षण करने के लिए, शब्द key
को poop
बदलें।
पायथन 3.x के लिए, iteritems()
को केवल items()
साथ प्रतिस्थापित किया गया है, जो एक सेट-जैसे दृश्य को निर्देशित करता है जैसे कि iteritems()
लेकिन इससे भी बेहतर। यह 2.7 में viewitems()
रूप में भी उपलब्ध है।
ऑपरेशन items()
2 और 3 दोनों के लिए काम करेगा, लेकिन 2 में यह डिक्शनरी (key, value)
जोड़े की एक सूची लौटाएगा, जो items()
कॉल के बाद होने वाले निर्देश में बदलावों को प्रतिबिंबित नहीं करेगा। यदि आप 3.x व्यवहार 2.x में चाहते हैं, तो आप list(d.items())
कॉल कर सकते हैं।