Given that in Python:
element = element + [0]
should be equal to:
element += [0]
Why does one modify a list and the other does not? Here is a example:
>>> a = [[0, 0], [0,0]]
>>> for element in a:
... element = element + [0]
...
>>> a
[[0, 0], [0, 0]]
a is not modified. But if I increment:
>>> a = [[0, 0], [0,0]]
>>> for element in a:
... element += [0]
...
>>> a
[[0, 0, 0], [0, 0, 0]]
a is modified.
Thanks, Frank
For a list, += is more like the extend method than like the append method. With a list to the left of the += operator, another list is needed to the right of the operator. All the items in the list to the right of the operator get added to the end of the list that is referenced to the left of the operator.
The set is far faster, in general. Testing for membership in a list is O(n), linear in the size of the list. Adding to a set is O(1), independent of the number of the items in the list.
Python provides a method called . append() that you can use to add items to the end of a given list.
This is a fun side-effect of +=
operatior, which calls __iadd__
instead of __add__
.
The statement x = x + y
is equivalent to x = x.__add__(y)
, while x += y
is equivalent to x = x.__iadd__(y)
.
This lets the list
class optimize +=
by extending the existing (ex, x += y
is roughly equivalent to x.extend(y)
) list instead of creating an entirely new list (which is what +
needs to do).
For example:
>>> a = [1, 2, 3] >>> original_a = a >>> b = [1, 2, 3] >>> original_b = b >>> a += [4] >>> b = b + [4] >>> a is original_a True >>> b is original_b False
You can see that using +=
maintains the identity of the left hand side (ie, a new list isn't created) while using +
does not maintain the identity (ie, a new list is created).
For more, see: http://docs.python.org/library/operator.html#operator.iadd and the paragraph directly above the documentation for operator.iadd
.
In the first case, element = element + [0], you are creating a new list.
In the second case, element += [0], you are modifying an existing list.
Since the list of lists, a, contains pointers to the elements, only modifying the elements will actually change things. (That is, creating a new list does not change the pointers in a.)
This is seen more clearly if we take a simple example showing how lists work:
>>> a = [1, 2, 3]
>>> b = a
>>> a = [4, 5, 6]
>>> a
[4, 5, 6]
>>> b
[1, 2, 3]
>>> a = [1, 2, 3]
>>> b = a
>>> a += [4, 5, 6]
>>> b
[1, 2, 3, 4, 5, 6]
>>> a
[1, 2, 3, 4, 5, 6]
Assigning a variable to a list simply assigns a pointer.
Adding to what others said, there is a difference in what these statements do:
element = element + [0]
does
element = element.__add__([0])
while
element += [0]
does
element = element.__iadd__([0])
__iadd__()
, in this case, is free to determine what to return: the original object with a modification or a new object.
In the case of a immutable object, it must return a different one (e.g., a = b = 8; a += 9
=> a is not b
.
But in the case of a mutable object, such as a list, it normally modifies this one:
a = b = []
a += [8]
=> a is b
.
This different behaviour reflects in your for loop:
for element in a:
element = element + [0]
=> name element
gets rebound to a different object; original one remains untouched
for element in a:
element += [0]
=> original object, which is as well contained in the outer list, a
, gets modified. The fact that element
is reassigned is irrelevant; it is not used.
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