अब मुझे पता है कि पुनरावृति के दौरान सूची को संशोधित करना सुरक्षित नहीं है। हालांकि, मान लीजिए कि मेरे पास स्ट्रिंग्स की एक सूची है, और मैं खुद स्ट्रिंग्स को स्ट्रिप करना चाहता हूं। क्या परिवर्तनशील मानों का प्रतिस्थापन संशोधन के रूप में होता है?
अब मुझे पता है कि पुनरावृति के दौरान सूची को संशोधित करना सुरक्षित नहीं है। हालांकि, मान लीजिए कि मेरे पास स्ट्रिंग्स की एक सूची है, और मैं खुद स्ट्रिंग्स को स्ट्रिप करना चाहता हूं। क्या परिवर्तनशील मानों का प्रतिस्थापन संशोधन के रूप में होता है?
जवाबों:
इसे खराब रूप माना जाता है। यदि आपको सूची के मौजूदा संदर्भों को बनाए रखने की आवश्यकता है, तो स्लाइस असाइनमेंट के बजाय एक सूची समझ का उपयोग करें।
a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)
print bस्टेटमेंट निष्पादित किया जाता है, तो आप बता सकते हैं कि क्या aबदले हुए स्थान पर संशोधित किया गया था। एक और संभावना यह print b is aदेखने की होगी कि क्या वे दोनों अभी भी एक ही वस्तु को संदर्भित करते हैं।
चूंकि नीचे का लूप केवल पहले से देखे गए तत्वों को संशोधित करता है, इसलिए इसे स्वीकार्य माना जाएगा:
a = ['a',' b', 'c ', ' d ']
for i, s in enumerate(a):
a[i] = s.strip()
print(a) # -> ['a', 'b', 'c', 'd']
जो इससे अलग है:
a[:] = [s.strip() for s in a]
इसमें उसे मूल की जगह एक अस्थायी सूची और इसके असाइनमेंट के निर्माण की आवश्यकता नहीं होती है, हालांकि इसके लिए अधिक अनुक्रमण संचालन की आवश्यकता होती है।
सावधानी: हालांकि आप प्रविष्टियों को इस तरह से संशोधित कर सकते हैं , आप listसमस्याओं का सामना करने की संभावना को जोखिम में डाले बिना मदों की संख्या को बदल नहीं सकते हैं ।
यहाँ एक उदाहरण है कि मेरा क्या मतलब है - एक प्रविष्टि को हटाना, उस बिंदु से अनुक्रमण को गड़बड़ाना:
b = ['a', ' b', 'c ', ' d ']
for i, s in enumerate(b):
if s.strip() != b[i]: # leading or trailing whitespace?
del b[i]
print(b) # -> ['a', 'c '] # WRONG!
(परिणाम गलत है क्योंकि इसमें उन सभी वस्तुओं को नहीं हटाया गया है जो होनी चाहिए।)
अपडेट करें
चूंकि यह एक काफी लोकप्रिय उत्तर है, यहां प्रविष्टियों को प्रभावी ढंग से "इन-प्लेस" हटाने के लिए है (भले ही यह बिल्कुल सवाल नहीं है):
b = ['a',' b', 'c ', ' d ']
b[:] = [entry for entry in b if entry.strip() == entry]
print(b) # -> ['a'] # CORRECT
for i in aहालांकि सिंटैक्स में अजगर केवल व्यक्तिगत तत्व की एक प्रति क्यों बनाता है ? यह बहुत ही सहज है, अन्य भाषाओं से अलग प्रतीत होता है और मेरे कोड में त्रुटियों के परिणामस्वरूप मुझे लंबे समय तक डिबग करना पड़ा। अजगर ट्यूटोरियल भी इसका उल्लेख नहीं करता है। हालांकि इसके कुछ कारण होने चाहिए?
a[i]और s) का उपयोग क्यों करें जब आपके पास नहीं है? मैं बहुत बल्कि करूँगा a[i] = a[i].strip()।
a[i] = s.strip()केवल एक अनुक्रमण ऑपरेशन करता है।
enumerate(b)हर पुनरावृत्ति पर एक अनुक्रमण ऑपरेशन करता है और आप एक दूसरे के साथ कर रहे हैं a[i] =। AFAIK लूप पायथन में केवल 1 अनुक्रमण संचालन के साथ पायथन में इस लूप को लागू करना असंभव है :(
लूप वैरिएंट के लिए एक, एन्यूमरेट () के साथ एक से अधिक क्लीनर दिखता है:
for idx in range(len(list)):
list[idx]=... # set a new value
# some other code which doesn't let you use a list comprehension
range(len(list))पायथन में एक कोड गंध की तरह कुछ का उपयोग करने पर विचार करते हैं ।
enumerateएक जेनरेटर है, जो लिस्ट नहीं बना रहा है। ट्यूपल्स, यह उन्हें एक बार में बनाता है क्योंकि यह सूची के माध्यम से पुनरावृत्त करता है। यह बताने का एकमात्र तरीका है कि कौन सा धीमा है timeit।
किसी सूची को पुनरावृत्ति करते समय प्रत्येक तत्व को संशोधित करना तब तक ठीक है, जब तक आप सूची में तत्वों को जोड़ने / हटाने को नहीं बदलते हैं।
आप सूची बोध का उपयोग कर सकते हैं:
l = ['a', ' list', 'of ', ' string ']
l = [item.strip() for item in l]
या सिर्फ C-styleलूप के लिए करें:
for index, item in enumerate(l):
l[index] = item.strip()
नहीं, आप सूची की "सामग्री" में परिवर्तन नहीं करेंगे, यदि आप इस तरह से तार बदल सकते हैं। लेकिन पायथन में वे परस्पर नहीं हैं। कोई भी स्ट्रिंग ऑपरेशन एक नया स्ट्रिंग लौटाता है।
यदि आपके पास उन वस्तुओं की एक सूची थी जिन्हें आप जानते थे कि आप परिवर्तनशील हैं, तो आप ऐसा तब तक कर सकते हैं जब तक आप सूची की वास्तविक सामग्री को नहीं बदलते।
इस प्रकार आपको किसी प्रकार का नक्शा बनाने की आवश्यकता होगी। यदि आप एक जनरेटर अभिव्यक्ति का उपयोग करते हैं तो यह [ऑपरेशन] किया जाएगा जैसा कि आप पुनरावृति करेंगे और आप मेमोरी को बचाएंगे।
Jemshit Iskenderov और Ignacio Vazquez-Abrams द्वारा दिया गया उत्तर वास्तव में अच्छा है। इसे इस उदाहरण के साथ आगे चित्रित किया जा सकता है: कल्पना कीजिए
क) दो वैक्टर के साथ एक सूची आपको दी गई है;
बी) आप सूची को पार करना चाहते हैं और सरणियों में से प्रत्येक के क्रम को उल्टा करना चाहते हैं
मान लीजिए कि आपके पास है
v = np.array([1, 2,3,4])
b = np.array([3,4,6])
for i in [v, b]:
i = i[::-1] # this command does not reverse the string
print([v,b])
तुम्हे मिल जाएगा
[array([1, 2, 3, 4]), array([3, 4, 6])]
दूसरी ओर, यदि आप करते हैं
v = np.array([1, 2,3,4])
b = np.array([3,4,6])
for i in [v, b]:
i[:] = i[::-1] # this command reverses the string
print([v,b])
परिणाम है
[array([4, 3, 2, 1]), array([6, 4, 3])]
यह आपके प्रश्न से स्पष्ट नहीं है कि स्ट्रिंग्स को हटाने का निर्णय लेने का मापदंड क्या है, लेकिन यदि आपके पास उन स्ट्रिंग्स की सूची है या जिन्हें आप हटाना चाहते हैं, तो आप निम्न कार्य कर सकते हैं:
my_strings = ['a','b','c','d','e']
undesirable_strings = ['b','d']
for undesirable_string in undesirable_strings:
for i in range(my_strings.count(undesirable_string)):
my_strings.remove(undesirable_string)
जो my_strings को ['a', 'c', 'e'] में बदलता है