4

我有这样的事情:

#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]

现在如果数组有 7 个元素,i 从 0 变为 6,并且在处理过程中,如果我删除一个数组元素,则新大小变为 6,但循环仍将运行直到 i=6 并访问令牌 [6 ] 并抛出错误,因为新大小为 6,即最大索引为 5。

我想我可以在某些条件下使用 while 循环,例如:

while(i<currMaxIndex)

我可以在其中动态更改 currMaxIndex。

但我真的很想知道是否有任何方法可以改变 for 循环本身中的 i 。

如果绝对必须知道,这是我的代码:

for i in xrange(0,len(tokens)):
            tokens[i]=tokens[i].translate(string.maketrans("",""),string.punctuation)
            if tokens[i]=='':
                del tokens[i]
4

2 回答 2

4

我会这样做:

def myfilter(token):
    return token.translate(None, string.punctuation)   

tokens = filter(None, map(myfilter, tokens))

如果逻辑太复杂无法通过map/filter来做,推荐使用这种方式:

for item in items[:]: # [:] copies the list
    if condition(item):
        items.remove(item)
于 2012-10-08T05:25:22.187 回答
2

len(tokens)在您创建xrange对象时计算,因此如果您从列表中删除元素,tokens[i]可能不存在或可能具有与您期望的不同的值。

例如:

>>> a = [1, 2, 3]
>>> a[1]
2
>>> del a[1]
>>> a[1]
3

与其修改原始列表,不如创建一个新列表:

new_tokens = []

for token in tokens:
    translated = token.translate(None, string.punctuation)

    if translated:
        new_tokens.append(translated)

或者您可以filter使用生成器表达式:

new_tokens = filter(None, (token.translate(None, string.punctuation) for token in tokens))
于 2012-10-08T05:15:57.247 回答