2011-12-17 32 views
8

के भीतर से पाइथन में लूप के इटरेटर को सही ढंग से संशोधित करने के तरीके को कैसे संशोधित करें, मुझे मूल रूप से एक सूची के प्रत्येक तत्व की जांच करने के लिए और यदि कुछ मानदंड फिट हैं तो मैं इसे सूची से हटाना चाहता हूं।लूप

इसलिए उदाहरण के लिए मान लें कि

सूची = [ 'एक', 'बी', 'सी', 'डी', 'ई']

मैं मूल रूप से (लिखने के लिए सिद्धांत रूप में चाहते हैं और वास्तविक कोड जो मैं लागू करने का प्रयास नहीं करता)

यदि सूची का कोई तत्व 'बी' या 'सी' सूची से हटा देता है और अगला लेता है।

लेकिन

for s in list: 
    if s=='b' or s=='c': 
     list.remove(s) 

में विफल रहता है, क्योंकि जब 'बी' पाश निकाल दिया जाता है अगले तत्व के रूप में 'प' लेता है और नहीं 'सी'। तो क्या अलग-अलग सूची में तत्वों को संग्रहीत करने और बाद में उन्हें हटाने से तेज़ करने का कोई तरीका है?

धन्यवाद।

उत्तर

9

आसान तरीका सूची की एक प्रति का उपयोग करने के है - यह एक टुकड़ा है कि "शुरू से ही" फैली सूची के "अंत" करने के लिए, इस तरह से किया जा सकता:

for s in list[:]: 
    if s=='b' or s=='c': 
     list.remove(s) 

आप इस पर विचार किया है, और यह आपके कोड में होने के लिए काफी आसान है, जब तक कि यह सूची वास्तव में बड़ी न हो, और कोड के महत्वपूर्ण भाग में (जैसे, एक्शन गेम के मुख्य लूप में)।

to_remove = [] 
for index, s in enumerate(list): 
    if s == "b" or s == "c": 
     to_remove.append(index) 

for index in reversed(to_remove): 
    del list[index] 

बेशक आप के बजाय एक समय पाश का सहारा कर सकते हैं::

index = 0 
while index < len(list): 
    if s == "b" or s == "c": 
     del list[index] 
     continue 
    index += 1 
+0

jsbueno आपको बहुत बहुत धन्यवाद। मुझे ऐसा सोचने के लिए थोड़ा शर्म आती है। एक बार फिर धन्यवाद! – tst

+0

मैं वास्तव में एक लूप के भीतर एक लूप चाहता था और आपका आखिरी उदाहरण सही था। एक बार फिर धन्यवाद। – tst

1

आप सूची आप कर सकते हैं की एक प्रति बनाकर ठीक लगता है उस मामले में, मैं कभी कभी निम्नलिखित मुहावरा का उपयोग ऐसा लगता है कि यह (list comprehension):

[s for s in list if s != 'b' and s != 'c'] 
8

इसका बेहतर चीजें हैं जो पहले से ही उपलब्ध हैं बदलने की नहीं। इन मामलों में filter फ़ंक्शन और लैम्ब्डा का उपयोग करें। यह अधिक पाइथोनिक और क्लीनर दिखता है।

filter(lambda x:x not in ['b','c'],['a','b','c','d','e']) 

वैकल्पिक रूप से आप सूची समझ

[x for x in ['a','b','c','d','e'] if x not in ['b','c']] 
+0

दरअसल, आपके दूसरे उदाहरण में सूची समझ फ़िल्टर और लैम्बडा संयोजन से "अधिक पायथनिक" है। – jsbueno

+0

धन्यवाद लेकिन मुझे एक ऐसे लूप को एक दूसरे में रखना होगा और इस तरह चीजें वास्तव में गन्दा हो सकती हैं। – tst

3

उपयोग कर सकते हैं यह वास्तव में क्या itertools.ifilter के लिए बनाया गया है।

from itertools import ifilter 

ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e']) 

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

list(ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e'])) 

या

[x for x in ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e'])]