यहां कोई भी उत्तर आपको वास्तव में यह बताने के लिए कोई कोड नहीं देता है कि पायथन भूमि में ऐसा क्यों होता है। और यह एक और अधिक गहरी दृष्टिकोण में देखने के लिए मजेदार है इसलिए यहां जाता है।
प्राथमिक कारण यह है कि आप अपेक्षा के अनुरूप काम नहीं करते हैं क्योंकि आप लिखते समय पायथन में हैं:
i += 1
यह वह नहीं कर रहा है जो आपको लगता है कि यह कर रहा है। पूर्णांक अपरिवर्तनीय हैं। यह तब देखा जा सकता है जब आप देखते हैं कि वास्तव में पायथन में क्या वस्तु है:
a = 0
print('ID of the first integer:', id(a))
a += 1
print('ID of the first integer +=1:', id(a))
आईडी फ़ंक्शन जीवनकाल में किसी वस्तु के लिए एक अद्वितीय और निरंतर मूल्य का प्रतिनिधित्व करता है। वैचारिक रूप से, यह C / C ++ में एक मेमोरी एड्रेस पर शिथिल रूप से मैप करता है। उपरोक्त कोड चलाना:
ID of the first integer: 140444342529056
ID of the first integer +=1: 140444342529088
इसका मतलब है कि पहला a
अब दूसरे के समान नहीं है a
, क्योंकि उनकी आईडी अलग हैं। प्रभावी रूप से वे स्मृति में विभिन्न स्थानों पर हैं।
एक वस्तु के साथ, हालांकि, चीजें अलग तरह से काम करती हैं। मैंने +=
यहाँ ऑपरेटर को अधिलेखित कर दिया है:
class CustomInt:
def __iadd__(self, other):
# Override += 1 for this class
self.value = self.value + other.value
return self
def __init__(self, v):
self.value = v
ints = []
for i in range(5):
int = CustomInt(i)
print('ID={}, value={}'.format(id(int), i))
ints.append(int)
for i in ints:
i += CustomInt(i.value)
print("######")
for i in ints:
print('ID={}, value={}'.format(id(i), i.value))
निम्न आउटपुट में यह परिणाम चल रहा है:
ID=140444284275400, value=0
ID=140444284275120, value=1
ID=140444284275064, value=2
ID=140444284310752, value=3
ID=140444284310864, value=4
######
ID=140444284275400, value=0
ID=140444284275120, value=2
ID=140444284275064, value=4
ID=140444284310752, value=6
ID=140444284310864, value=8
ध्यान दें कि इस मामले में आईडी विशेषता वास्तव में दोनों पुनरावृत्तियों के लिए समान है , भले ही ऑब्जेक्ट का मूल्य अलग है (आप ऑब्जेक्ट को id
रखने वाले इंट वैल का भी पता लगा सकते हैं , जो बदलते हुए के रूप में बदल रहा होगा - क्योंकि पूर्णांक अपरिवर्तनीय हैं)।
जब आप एक अपरिवर्तनीय वस्तु के साथ एक ही व्यायाम चलाते हैं तो इसकी तुलना करें:
ints_primitives = []
for i in range(5):
int = i
ints_primitives.append(int)
print('ID={}, value={}'.format(id(int), i))
print("######")
for i in ints_primitives:
i += 1
print('ID={}, value={}'.format(id(int), i))
print("######")
for i in ints_primitives:
print('ID={}, value={}'.format(id(i), i))
यह आउटपुट:
ID=140023258889248, value=0
ID=140023258889280, value=1
ID=140023258889312, value=2
ID=140023258889344, value=3
ID=140023258889376, value=4
######
ID=140023258889280, value=1
ID=140023258889312, value=2
ID=140023258889344, value=3
ID=140023258889376, value=4
ID=140023258889408, value=5
######
ID=140023258889248, value=0
ID=140023258889280, value=1
ID=140023258889312, value=2
ID=140023258889344, value=3
ID=140023258889376, value=4
ध्यान देने योग्य कुछ बातें। सबसे पहले, के साथ लूप में +=
, आप अब मूल ऑब्जेक्ट में नहीं जोड़ रहे हैं। इस मामले में, क्योंकि चींटियाँ पायथन में अपरिवर्तनीय प्रकारों में से हैं , अजगर एक अलग आईडी का उपयोग करता है। यह भी दिलचस्प है कि पायथन एक id
ही अपरिवर्तनीय मूल्य के साथ कई चर के लिए अंतर्निहित का उपयोग करता है :
a = 1999
b = 1999
c = 1999
print('id a:', id(a))
print('id b:', id(b))
print('id c:', id(c))
id a: 139846953372048
id b: 139846953372048
id c: 139846953372048
tl; dr - पायथन में मुट्ठी भर अपरिवर्तनीय प्रकार होते हैं, जो आपके द्वारा देखे जाने वाले व्यवहार का कारण बनते हैं। सभी उत्परिवर्तनीय प्रकारों के लिए, आपकी अपेक्षा सही है।
i
आप अपरिवर्तनीय हैं या आप एक नॉन-म्यूटिंग ऑपरेशन कर रहे हैं। एक नेस्टेड सूची के साथfor i in a: a.append(1)
अलग व्यवहार होगा; पायथन नेस्टेड सूचियों की नकल नहीं करता है। हालाँकि पूर्णांक अपरिवर्तनीय हैं और इसके अलावा एक नई वस्तु मिलती है, यह पुराने को नहीं बदलता है।