请参阅下面的代码。我在运行下面的代码时不断收到此错误:
"IndexError: list index out of range"
代码:
for x in range(0, numFiles):
print(fileList[x])
for x in range(0, numFiles):
f = open(dirName + "/" + fileList[x], 'r') # open the file for reading
fileText = f.read() # read file contents into string
f.close() # close file
if fileText.find(tagName) == -1: # if the file text doesn't contain the tag
fileList.remove(fileList[x]) # then remove the file from the file list
第一个for循环用于调试,它按预期工作,但第二个for循环,我试图实际打开文件,使索引超出范围错误。任何帮助将不胜感激。
答案 0 :(得分:1)
执行fileList.remove
后,如果fileText.find(tagName) == -1
(您正在更改for
循环中迭代的列表长度),则会使列表变小
请参阅此简化示例:
test_list = [1, 2, 3, 4, 5]
num_items = len(test_list)
for i in range(0, num_items):
print("Dealing with i=%s" % i)
data = test_list[i]
if data == 2 or data == 3 or data == 4:
print("Removing i=%s (data=%s)" % (i, data))
test_list.remove(data)
print("Now test_list=%s, with %s items" % (test_list, len(test_list)))
哪个输出:
Dealing with i=0
Now test_list=[1, 2, 3, 4, 5], with 5 items
Dealing with i=1
Removing i=1 (data=2)
Now test_list=[1, 3, 4, 5], with 4 items
Dealing with i=2
Removing i=2 (data=4)
Now test_list=[1, 3, 5], with 3 items
Dealing with i=3
Traceback (most recent call last):
File "./stack_101.py", line 25, in <module>
data = test_list[i]
IndexError: list index out of range
由于您只需要“访问”一次文件,我建议您将循环更改为while
:
test_list = [1, 2, 3, 4, 5]
num_items = len(test_list)
i = 0
while i < len(test_list):
data = test_list[i]
print("Dealing with i=%s (data=%s)" % (i, data))
if data == 2 or data == 3 or data == 4:
print("Removing i=%s, data=%s. NOT advancing" % (i, data))
test_list.remove(data)
else:
i += 1
print("Advancing counter to i=%s because we didn't remove the entry" % i)
print("Now test_list=%s, with %s items" % (test_list, len(test_list)))
print("After the loop, test_list=%s" % test_list)
正确输出:
Dealing with i=0 (data=1)
Advancing counter to i=1 because we didn't remove the entry
Now test_list=[1, 2, 3, 4, 5], with 5 items
Dealing with i=1 (data=2)
Removing i=1, data=2. NOT advancing
Now test_list=[1, 3, 4, 5], with 4 items
Dealing with i=1 (data=3)
Removing i=1, data=3. NOT advancing
Now test_list=[1, 4, 5], with 3 items
Dealing with i=1 (data=4)
Removing i=1, data=4. NOT advancing
Now test_list=[1, 5], with 2 items
Dealing with i=1 (data=5)
Advancing counter to i=2 because we didn't remove the entry
Now test_list=[1, 5], with 2 items
After the loop, test_list=[1, 5]
但是:真的是否需要更改列表?正如您所看到的,这会扰乱代码并导致复杂化。如何使用未删除的文件创建新列表?
类似的东西:
test_list = [1, 2, 3, 4, 5]
num_items = len(test_list)
new_list = []
for i in range(0, num_items):
data = test_list[i]
print("Dealing with i=%s (data=%s)" % (i, data))
if not(data == 2 or data == 3 or data == 4):
print("Keeping i=%s (data=%s)" % (i, data))
new_list.append(data)
print("After the loop, new_list=%s" % new_list)
在new_list
中留下“正确”的值:
Dealing with i=0 (data=1)
Keeping i=0 (data=1)
Dealing with i=1 (data=2)
Dealing with i=2 (data=3)
Dealing with i=3 (data=4)
Dealing with i=4 (data=5)
Keeping i=4 (data=5)
After the loop, new_list=[1, 5]
应用于您的代码我想它会是这样的(未经测试):
found_files = []
for x in range(0, numFiles):
f = open(dirName + "/" + fileList[x], 'r') # open the file for reading
fileText = f.read() # read file contents into string
f.close() # close file
if fileText.find(tagName) >= 0: # if the file text contains the tag
found_files.append(fileList[x]) # then add it to the new list
答案 1 :(得分:0)
要避免超出范围错误,请尝试以下操作:
for f in fileList:
< CODE HERE > # f will be the actual file name now
如果您想保留索引,请尝试以下方法:
for i, f in enumerate(fileList):
< CODE HERE > # i will be a counter and f will be the actual file name
编辑 - 抱歉,您甚至没有注意到您正在动态更改列表大小。这就是索引错误!
答案 2 :(得分:0)
正如其他人指出的那样,你要从列表中删除元素,这个索引超出了列表的当前大小,小于numFiles。
解决问题的方法是:
for x in range(0, numFiles):
print(fileList[x])
last_index = numFiles
x = 0
while x < last_index:
f = open(dirName + "/" + fileList[x], 'r')
fileText = f.read()
f.close()
if fileText.find(tagName) == -1:
fileList.pop(x) #pop is better, less ambiguous in case there is duplicates
last_index -= 1 #Decrement the end of the loop
else:
x += 1 #go to the next index only if you didn't remove an item
答案 3 :(得分:0)
感谢BorrajaX和上面的其他类似建议,我决定第二次尝试解决方案,但这次采用的方法略有不同。我没有从复制的列表中删除,而是创建了一个新的空列表,如果找到了标记名称,则会附加到该列表中。而且效果很好!在这里感谢大家的帮助!如果有人有兴趣,请修改以下代码。
for x in range(0, numFiles):
print(fileList[x])
resultFileList = []
for x in range(0, numFiles):
f = open(dirName + "/" + fileList[x], 'r') # open the file for reading
fileText = f.read() # read file contents into string
f.close() # close file
if fileText.find(tagName) >= 0: # if the file text doesn't contain the tag
resultFileList.append(fileList[x]) # then remove the file from the file list