Python索引器错误:列表索引超出范围,即使检查是否为空

2024-06-16 10:13:02 发布

您现在位置:Python中文网/ 问答频道 /正文

在以下代码行中,索引器错误列表索引超出范围:

if tweetSplit[i] != "":

在我的代码中:

^{pr2}$

我想通过使用“if not tweetSplit”检查tweetSplit是否为空,我不会遇到超出范围的错误。 以下是完整的错误:

Traceback (most recent call last):
  File "parseTweets.py", line 55, in <module>
     if tweetSplit[i] != "":
IndexError: list index out of range

Tags: 代码most列表if错误notcallfile
3条回答

由于以下原因,您将得到一个IndexError

del tweetSplit[i]

结果是您正在删除tweetSplit中的元素。这会导致tweetSplit的长度缩短。在

要解决此问题,请不要从tweetSplit中删除任何元素。只需浏览一下列表。不需要删除任何元素。在

如果不需要处理任何索引,只需在Python中使用for-each循环。在

for tweet in tweetSplit:
    if tweet != "" and tweet[:1] == '@':
        # Do something but don't delete any tweet from tweetSplit.

你的测试没什么用。在

确定if not tweetsplit:检查tweetsplit是否为空。但是它不检查tweetsplit是否至少是i+1个元素的长度。在

而且,因为您在循环的中间从tweetsplit中删除,如果您删除哪怕一个元素,那么到最后,它将比i+1短,并引发一个{}。在

这就是在循环任何集合的过程中不应该删除或插入的原因之一。(但不是唯一一个,例如,当您删除元素i时,它会将所有其他元素向上移动一个插槽,然后检查新元素i+1,它原来是i+2……这意味着您错过了一个。)


如果你想建立一个符合某些规则的所有tweet的集合,那么通过构建一个新列表来实现这一点要容易得多:

goodTweets = []
for tweet in tweetSplit:
    if tweet[:1] != '@':
        goodTweets.append(tweet)

或者:

^{pr2}$

如果因为某种原因确实需要对tweetSplit进行变异,可以使用一些技巧,但是它们都有点难看。在

构建一个新列表,然后将tweetSplit更改为该列表:

^{3}$

或者,在不显式构建新列表的情况下执行此操作:

tweetSplit[:] = (tweet for tweet in tweetSplit if tweet[:1] != '@')

或者向后迭代。虽然len(tweetSplit)可能会随着删除而更改,但0永远不会更改。(虽然i:中的任何东西的位置都可能改变,:i的位置永远不会改变。)

for i in range(len(tweetSplit))[::-1]:
    if tweetSplit[i][:1] == '@':
        del tweetSplit[i]

但是,如果您试图将此作为性能优化进行到位,那么所有这些通常都会比较慢。唯一可能更快的方法是:

i = 0
while i < len(tweetSplit):
    if tweetSplit[i][:1] == '@':
        tweetSplit[i] = tweetSplit[-1]
        tweetSplit.pop()
    else:
        i += 1

如果您现在不确定tweetSplit[i]是否在范围内,可以改为使用类似于:

if isinstance(tweetSplit[i], str):

如果tweetSplit[i]的值是string类型,则返回一个布尔值。在

但是,使用从tweetSplit数组中删除值的方式,很可能会遇到索引方式的问题。在

相关问题 更多 >