迭代list和pop() - 元素时索引错误

时间:2016-06-28 15:18:36

标签: python for-loop indexing

import os
os.chdir('G:\\f5_automation')
r = open('G:\\f5_automation\\uat.list.cmd.txt')
#print(r.read().replace('\n', ''))
t = r.read().split('\n')
for i in range(len(t)):
    if ('inherited' or 'device-group' or 'partition' or 'template' or 'traffic-group') in t[i]:
        t.pop(i)
        print(i,t[i])

在上面的代码中,我在第9行遇到索引错误:' if(' inherited'或' device-group' ... etc。

我真的不明白为什么。如果使用len(t)作为我的范围,我的指数如何超出范围?

目标是从列表中弹出包含任何子字符串的任何索引。谢谢你的帮助!

3 个答案:

答案 0 :(得分:0)

这是因为您在循环浏览列表时正在编辑列表, 你首先得到10的长度,然后你循环10次。但是一旦你删除了一件事,那么列表只会是9长。 解决这个问题的方法是创建一个新的要保留的列表,然后使用该列表。

我对您的代码稍作编辑并做了类似的事情。

t = ['inherited', 'cookies', 'device-group']

interesing_things = []
for i in t:
    if i not in ['inherited', 'device-group', 'partition', 'template', 'traffic-group']:
        interesing_things.append(i)
        print(i)

答案 1 :(得分:0)

正如许多人在评论中所说,您的代码存在一些问题。

or运算符将左侧和右侧的值视为布尔值,并返回第一个True(从左到右)的值。所以你的括号计算为'inherited',因为任何非空字符串都是True。因此,即使您的for loop正在运行,您也会弹出仅等于“继承”的元素。

for loop无效。之所以发生这种情况是因为您循环遍历的列表大小正在改变,如果列表中的元素实际上等于“继承”并且弹出,您将得到索引超出范围的错误。

所以,看看这个:

import os
os.chdir('G:\\f5_automation')
r = open('G:\\f5_automation\\uat.list.cmd.txt')
print(r.read().replace('\n', ''))
t = r.read().split('\n')
t_dupl = t[:]
for i, items in enumerate(t_dupl):
    if items in ['inherited', 'device-group', 'partition', 'template', 'traffic-group']:
        print(i, items)
        t.remove(items)

通过复制原始列表,我们可以将其项目用作项目的“池”来挑选和修改我们实际感兴趣的列表。

最后,要知道pop()方法返回它从列表中删除的项目,这是您在示例中不需要的内容。 remove()适用于您。

作为旁注,您可以用以下代码替换前5行代码:

with open('G:\\f5_automation\\uat.list.cmd.txt', 'r') as r:
    t = r.readlines()

使用with语句的优点是它在读取完成后自动处理文件的关闭。最后,您可以使用内置的readlines()方法,而不是读取整个文件并将其拆分为换行符。

答案 2 :(得分:0)

我们说len(t) == 5

我们会处理值i

[0,1,2,3,4]

我们处理i = 0后,会从t中弹出一个值。 len(t) == 4现在。如果我们到达i = 4,这将意味着错误。但是,我们仍然会尝试达到4,因为我们的range已经达到了4

下一步(i = 1)步骤可确保i = 3上出现错误。

下一步(i = 2)步骤可确保i = 2出错,但已经处理过。

下一步(i = 3)步骤会产生错误。

相反,你应该这样做:

while t:
    element = t.pop()
    print(element)

另外,您应该将in支票替换为套装:

qualities_we_need = {'inherited', 'device-group', 'partition'} # put all your qualities here

然后循环:

if qualities_we_need & set(element):
    print(element)

如果您需要索引,可以使用另外一个变量来跟踪我们当前正在处理的值索引,或者使用enumerate()