So I am getting a list index out of range error in python again, and I can't figure out what's wrong.
#!/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()
I made sure that the a duplicated list is being modified as the primary list is iterated over, so that can't be the problem.
Appreciate any help Thanks :)
You only duplicated a reference to the list. If you want to make a separate copy of a list, use slices: list2 = list1[:]
or look into the deepcopy
module.
When you pop, the array size goes down. That means if the list has length 10, and you pop(0)
, then the list has length 9. If you then pop(9)
, which doesn't exist it will give you an out of bounds error.
Example:
>>> 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
This is an error in your case because you go from 0 to len(new_list1).
The approach I advise you to take is to create a new list where "Reactome" is not in new_list1[i].
You can do this easily in a list comprehension.
with open("membrane_GO.txt","r") as f:
lines = [line for line in f.readlines() if "Reactome" not in line]
print lines
Assume that your list is initially ['a', 'b', 'c'],
then list1 = list2 = ['a', 'b', 'c']
Then you perform iteration for len(list2)
, ie 3 times, Then i
will take values 0, 1, and 2.
In each iteration you are removing one element from 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.
So you will get a index out of bound error
Just to add to TigerHawks answer:
Because you have only duplicated the reference (not the list itself), when you pop()
an element out of new_list2
, you also remove it from new_list1
beceause they're both references to the same list.
Say there are 'n' elements in new_list1
at the start of the loop . It will run for 'n' iterations.
Suppose then that you pop an element out of new_list2
(and so out of new_list1
as well), within the loop, you will get an index out of range
error when the loop tries to access the 'nth' element of a list which now only has 'n-1' elements in it
For this to work properly use slicing to copy the list:
new_list2 = new_list1[:]
Incidentally, for i in range(len(new_list1)):
is considered un-pythonic, I believe. A 'better' way would be to use enumerate :
for index, element in enumerate(new_list1):
if "Reactome" in element:
new_list2.pop(index)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.