This question already has an answer here:
I'm trying to modify items in a list using a for loop, but I get an error (see below). Sample code:
#!/usr/bin/env python
# *-* coding: utf8 *-*
data = []
data.append("some")
data.append("example")
data.append("data")
data.append("here")
for item in data:
data[item] = "everything"
Error:
Traceback (most recent call last):
File "./testy.py", line 11, in <module>
data[item] = "everything"
TypeError: list indices must be integers, not str
Is there any way to solve this problem?
Try this instead:
The basic problem you're having is that when you write
data[i]
, withdata
being a list, thei
needs to be an integer, a numerical index into the list. But in the loopitem
is the actual thing that's in the list, i.e. a string, not the numerical index of the thing.xrange
is an iterator that produces numbers instead of the values in the list, so you can use that.An alternative would be
The
enumerate
function gives you an iterator over tuples of the form(index, item)
, so all you need to do is take the index and forget about the item. I'm not sure that one way or the other (enumerate
orxrange
) will be significantly faster or better, since I think lists store their length in a variable so it can be quickly accessed without counting through the list elements.However, if you need the old list value to compute the new list value, the
enumerate
way will probably be slightly faster because you avoid making Python look up the element in the list:This sort of thing is better expressed as a list comprehension, though:
When you do this, Python will go through each item in
data
, apply the function to it, and construct a new list from the results automatically, so you don't need to worry about putting the result offunc(item)
in the right place in the list. Your original example could actually be expressed asthe indexing of a list using integers could be inefficient. It is likely that python stores list elements using linked table with underlying pointers. In this case, to find a specific item, python have to traverse the list until the i-th item.
It is suggested that using the format like this could be efficient: a[:] = [x*x for x in a]
List items are accessed by integer index, i. e. in your example
data[1] == 'example'
. This is why Python complains when you're using a string as a lookup.If you want to find an element in a list by its value, you can use
data.index("value")
:But if you just want to loop over them, use
enumerate()
as David suggested.