I tried the following code on Python, and this is what I got: It seems like for many changes I try to make to the iterables by changing elem, it doesn't work.
lis = [1,2,3,4,5]
for elem in lis:
elem = 3
print lis
[1, 2, 3, 4, 5]
However if the iterables are objects with its own methods (like a list), they can be modified in a for loop.
lis = [[1],[2]]
for elem in lis:
elem.append(8)
print lis
[[1, 8], [2, 8]]
In the for
loop what exactly is the 'elem' term? Thanks in advance!
The reason that this doesn't work is because you're misunderstanding what elem
is. It's not the object itself, and it's not even correct to call it a "variable".
It's a name, kind of like a label, that points to the object. If you just directly assign over it, you're just overwriting the name to point at something else. But, you still have the original reference to the list, so assigning a different value over elem
doesn't modify lis
itself.
Now, in this case, since all of the objects that elem
points to are integers, you can't even change them at all - because integers (and many other types, like strings or tuples) are immutable. That means, simply put, that once the object has been created it cannot be modified. It has nothing to do with whether they "have methods" or not (all Python objects have methods, integers included), but on whether or not they are immutable.
Some objects, however, are mutable, meaning that they can be changed. Lists are examples of such objects. In your second example, elem
is a name that references the list objects contained within lis
, which themselves are mutable. That is why modifying them in-place (using .append()
, or .remove()
, etc) works fine.
The elem
variable in your for
loop is a reference to the current object on each iteration. Changing it won't do anything; it will just change the value of the variable elem
and that's going to be changed the next time through the loop anyway. To actually change the value of the element in the list, you need a reference to the list and the index of the element to be changed, and you don't have the latter.
So what you want to do is something like this:
for index, elem in enumerate(lis):
lis[index] = 3
This way you have elem
for the element's value and index
for the position in the list. It saves you from writing lis[index]
constantly to get values, but you must still do so to change elements.
You can also do:
for index in xrange(len(lis)):
lis[index] = 3
However, in most situations this is considered un-Pythonic (among other things, what happens if the list gets longer or shorter while it's being iterated)?
Here, you are actually modifying the list object in your second example. In the first example, you are not modifying the number, you are replacing it. This can be a complicated nuance for new users of Python.
Check this out:
>>> x = 1
>>> id(x)
4351668456
>>> x = 2
>>> id(x)
4351668432
id
returns the identifier of the object. As you can see above, the object of x
changes both of these times.
>>> y = [1]
>>> id(y)
4353094216
>>> y.append(2)
>>> id(y)
4353094216
Here, I modify the list, so the list is still the original object y
.
So, all this means that when you are doing elem = 3
, it's not modifying it, it is replacing it. And by now, it's not associated with the list anymore.
This is one of the ways you could do what you are trying to do. This grabs the index and then modifies the list, not the number.
lis = [1,2,3,4,5]
for idx, elem in enumerate(lis):
lis[idx] = 3
print lis
[1, 2, 3, 4, 5]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With