2015-04-01 175 views
0

所以我再次得到一个超出范围错误的列表索引,我无法弄清楚什么是错的。列表索引超出范围错误

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

f1 = open("membrane_GO.txt","r") 
new_list1 = f1.readlines() 
new_list2 = new_list1 
for i in range(len(new_list1)): 
    if "Reactome" in new_list1[i]: 
     new_list2.pop(i) 
print new_list2 
f1.close() 

我确保重复列表正在被修改,因为主列表被迭代,所以不能成为问题。

感谢所有帮助 谢谢:)

回答

2

你只复制到列表的引用。如果要制作单独的副本,请使用片:list2 = list1[:]或查看deepcopy模块。

+0

如果您复制或不复制,则无关紧要。一旦弹出,其中一个的长度将会改变。这意味着,您无法在第一次弹出后从副本中正确弹出。 – ProfOak 2015-04-01 08:11:06

2

弹出时,数组大小下降。这意味着如果列表的长度为10,而你的列表的长度为pop(0),那么列表的长度为9.如果你的话pop(9)不存在,它会给你一个界外的错误。

例子:

>>> x = [0,1,2,3,4] 
>>> print x, len(x) 
[0,1,2,3,4], 5 
>>> x.pop(0) 
>>> print x, len(x) 
[1,2,3,4], 4 

这是你的情况的错误,因为你从0到LEN(new_list1)。

我建议您采取的方法是创建一个新列表,其中“Reactome”不在new_list1 [i]中。

你可以在列表理解中轻松地做到这一点。

with open("membrane_GO.txt","r") as f: 
    lines = [line for line in f.readlines() if "Reactome" not in line] 
print lines 
1

假设您的列表最初为[ '一', 'B', 'C'],

然后list1 = list2 = ['a', 'b', 'c']

然后你len(list2)进行迭代,即3倍, 然后i将取值0,1和2.

在每次迭代中,您将从list1中删除一个元素。

i = 0 
remove list1[0] 
new list = ['b', 'c'] 

i = 1 
remove list1[1] 
new list = ['b'] 

i = 2 
remove list[2] which does not exist. 

所以,你会得到一个index out of bound error

0

只需添加到TigerHawks答案:

因为你只有复制引用(不在名单本身),当你pop()new_list2元素,您还将其从new_list1中删除,因为它们都是对同一列表的引用。

假设new_list1在'开始时有'n'个元素。它将运行'n'迭代。

假设那么你弹出一个元素出来的new_list2(等出来的new_list1为好),内环路,你会得到一个index out of range错误当环路试图现在访问列表,它的“第n个”元素只有在它

“N-1”分子为了这个正常工作使用切片复制的清单:

new_list2 = new_list1[:] 

顺便说一句,for i in range(len(new_list1)):被认为是未Python的,我相信。 '更好'的方式是使用enumerate

for index, element in enumerate(new_list1): 
    if "Reactome" in element: 
     new_list2.pop(index)