Reputation: 1845
I have something like this :
#tokens is a list of a few words
for i in xrange(0,len(tokens)):
#some code to modify the contents of token[i]
if tokens[i] == some value:
del tokens[i]
Now if the array has 7 elements, i goes from 0 to 6, and in the middle of the processing if I delete an array element, then the new size becomes 6 but the loop will still run till i=6 and access tokens[6] and throw an error because the new size is 6 i.e. max index is 5.
I guess I can use a while loop with some condition like:
while(i<currMaxIndex)
where I can dynamically change currMaxIndex.
But I was just really curious to know if there was any way to alter i in the for loop itself.
If absolutely MUST know, this is my code:
for i in xrange(0,len(tokens)):
tokens[i]=tokens[i].translate(string.maketrans("",""),string.punctuation)
if tokens[i]=='':
del tokens[i]
Upvotes: 4
Views: 188
Reputation: 27591
I would do this:
def myfilter(token):
return token.translate(None, string.punctuation)
tokens = filter(None, map(myfilter, tokens))
If the logic is too complicated to do it through the map / filter, it is recommended to use this approach:
for item in items[:]: # [:] copies the list
if condition(item):
items.remove(item)
Upvotes: 4
Reputation: 298106
len(tokens)
is computed when you create the xrange
object, so if you are deleting elements from the list, tokens[i]
may not exist or may have a value that is different from what you'd expect.
For example:
>>> a = [1, 2, 3]
>>> a[1]
2
>>> del a[1]
>>> a[1]
3
Instead of modifying the original list, create a new one:
new_tokens = []
for token in tokens:
translated = token.translate(None, string.punctuation)
if translated:
new_tokens.append(translated)
Or you can filter
a generator expression:
new_tokens = filter(None, (token.translate(None, string.punctuation) for token in tokens))
Upvotes: 2