यह उत्तर मूल रूप से एक प्रश्न के उत्तर में लिखा गया था, जिसे तब से डुप्लिकेट के रूप में चिह्नित किया गया है:
अजगर पर सूची से निर्देशांक हटाते हुए
आपके कोड में दो समस्याएं हैं:
1) हटाने () का उपयोग करते समय, आप पूर्णांक को हटाने का प्रयास करते हैं, जबकि आपको टपल को निकालने की आवश्यकता होती है।
2) लूप के लिए आपकी सूची में आइटम छोड़ देंगे।
जब हम आपके कोड को निष्पादित करते हैं तो क्या होता है:
>>> L1 = [(1,2), (5,6), (-1,-2), (1,-2)]
>>> for (a,b) in L1:
... if a < 0 or b < 0:
... L1.remove(a,b)
...
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
TypeError: remove() takes exactly one argument (2 given)
पहली समस्या यह है कि आप हटाने के लिए 'a' और 'b' दोनों पास कर रहे हैं (), लेकिन remove () केवल एक ही तर्क को स्वीकार करता है। तो हम आपकी सूची के साथ ठीक से काम करने के लिए कैसे निकाल सकते हैं ()? हमें यह पता लगाने की आवश्यकता है कि आपकी सूची का प्रत्येक तत्व क्या है। इस मामले में, प्रत्येक एक टपल है। इसे देखने के लिए, आइए सूची के एक तत्व तक पहुँचें (अनुक्रमण 0 से शुरू होता है):
>>> L1[1]
(5, 6)
>>> type(L1[1])
<type 'tuple'>
अहा! एल 1 का प्रत्येक तत्व वास्तव में एक टपल है। इसलिए इसे हटाने के लिए हमें पास होने की जरूरत है ()। अजगर में ट्यूपल्स बहुत आसान हैं, वे बस कोष्ठक में मूल्यों को संलग्न करके बनाए जाते हैं। "ए, बी" एक टपल नहीं है, लेकिन "(ए, बी)" एक टपल है। इसलिए हम आपके कोड को संशोधित करते हैं और इसे फिर से चलाते हैं:
# The remove line now includes an extra "()" to make a tuple out of "a,b"
L1.remove((a,b))
यह कोड बिना किसी त्रुटि के चलता है, लेकिन आइए इसकी आउटपुट सूची को देखें:
L1 is now: [(1, 2), (5, 6), (1, -2)]
आपकी सूची में अभी भी (1, -2) क्यों है? यह सूची को संशोधित करता है जबकि एक लूप का उपयोग करने के लिए यह विशेष देखभाल के बिना एक बहुत बुरा विचार है। सूची में बने रहने का कारण (1, -2) यह है कि सूची के भीतर प्रत्येक आइटम के स्थान लूप के पुनरावृत्तियों के बीच बदल गए। आइए देखें कि क्या होता है अगर हम उपरोक्त कोड को एक लंबी सूची खिलाते हैं:
L1 = [(1,2),(5,6),(-1,-2),(1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
### Outputs:
L1 is now: [(1, 2), (5, 6), (1, -2), (3, 4), (5, 7), (2, 1), (5, -1), (0, 6)]
जैसा कि आप उस परिणाम से अनुमान लगा सकते हैं, हर बार जब सशर्त कथन सत्य का मूल्यांकन करता है और एक सूची आइटम हटा दिया जाता है, तो लूप का अगला पुनरावृत्ति सूची में अगले आइटम का मूल्यांकन छोड़ देगा क्योंकि इसके मूल्य अब अलग-अलग सूचकांकों पर स्थित हैं।
सबसे सहज समाधान सूची की नकल करना है, फिर मूल सूची पर पुनरावृत्ति करना और केवल प्रतिलिपि को संशोधित करना है। आप ऐसा करने की कोशिश कर सकते हैं:
L2 = L1
for (a,b) in L1:
if a < 0 or b < 0 :
L2.remove((a,b))
# Now, remove the original copy of L1 and replace with L2
print L2 is L1
del L1
L1 = L2; del L2
print ("L1 is now: ", L1)
हालाँकि, आउटपुट पहले के समान होगा:
'L1 is now: ', [(1, 2), (5, 6), (1, -2), (3, 4), (5, 7), (2, 1), (5, -1), (0, 6)]
ऐसा इसलिए है क्योंकि जब हमने L2 बनाया था, तो अजगर ने वास्तव में एक नई वस्तु नहीं बनाई थी। इसके बजाय, उसने L2 को L1 के समान ऑब्जेक्ट के लिए संदर्भित किया। हम इसे 'is ’के साथ सत्यापित कर सकते हैं जो केवल" बराबर "(==) से अलग है।
>>> L2=L1
>>> L1 is L2
True
हम copy.copy () का उपयोग करके एक सच्ची प्रतिलिपि बना सकते हैं। फिर सब कुछ उम्मीद के मुताबिक काम करता है:
import copy
L1 = [(1,2), (5,6),(-1,-2), (1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
L2 = copy.copy(L1)
for (a,b) in L1:
if a < 0 or b < 0 :
L2.remove((a,b))
# Now, remove the original copy of L1 and replace with L2
del L1
L1 = L2; del L2
>>> L1 is now: [(1, 2), (5, 6), (3, 4), (5, 7), (2, 1), (0, 6)]
अंत में, L1 की पूरी तरह से नई प्रतिलिपि बनाने की तुलना में एक क्लीनर समाधान है। उलटा () फ़ंक्शन:
L1 = [(1,2), (5,6),(-1,-2), (1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
for (a,b) in reversed(L1):
if a < 0 or b < 0 :
L1.remove((a,b))
print ("L1 is now: ", L1)
>>> L1 is now: [(1, 2), (5, 6), (3, 4), (5, 7), (2, 1), (0, 6)]
दुर्भाग्य से, मैं पर्याप्त रूप से वर्णन नहीं कर सकता कि कैसे उलट () काम करता है। जब कोई सूची पास हो जाती है, तो वह 'listreverseiterator' ऑब्जेक्ट देता है। व्यावहारिक उद्देश्यों के लिए, आप इसके तर्क की उलटी प्रतिलिपि बनाने के रूप में सोच सकते हैं। यह वह उपाय है जो मैं सुझाता हूं।