The Cost of Dynamism (was Re: Pyhon 2.x or 3.x, which is faster?)

Steven D'Aprano steve at pearwood.info
Thu Mar 24 13:44:00 EDT 2016


On Fri, 25 Mar 2016 01:16 am, BartC wrote:

> Or is the Pythonic way, when you want to change some elements of a list
> to just build a new one that incorporates those changes?


If you are only changing a few elements, or one at a time in some random
order, then just change the element. Lists have random access, so you can
easily change a single item:

mylist[975] = "Hello world"


But if you intend to change the entire list, *in general* it is faster to
create a new list and copy the items into the old list. This is called
*slicing*, to be specific, we're assigning to a "slice" corresponding to
the entire list:

mylist[:] = newlist

But we don't have to assign to the entire list. We can assign to a sublist:

mylist[2:102] = newlist

and mylist will shrink or expand as needed.

It is most convenient to use the list replication operator * to build the
new list:

[0, 1]*100  # like [0, 1, 0, 1, 0, 1, 0, 1, ... , 0, 1]

or a list comprehension:

[i**2 for i in range(100)]  # like [0**2, 1**2, 2**2, 3**3, 4**2, ... 99**2]


But most of the time you might not even care about modifying the list in
place. Why spend the time to copy the new list over? Just reassign the
variable to the new list.


mylist = [i**2 for i in range(100)]



The difference between mylist = ... and mylist[:] = ... comes down to what
happens to other references. Suppose you have some object with a list
attribute:


instance.data = [1, 2, 3]

Now we bind that list to another name (say, you pass it to a function, where
the list gets assigned to a local variable):

mylist = instance.data


mylist and instance.data both "point to" the same underlying list object.
Modifications to one will be seen by the other, as they both refer to the
same list. If you do 

mylist[:] = ...

that is an in-place modification of the list, and will be seen by all
references to that list. But if you do 

mylist = ...

that is a binding operation, and it reassigns the name "mylist" without
touching the list object itself, or the instance.data reference.

Analogy: if Barack Obama cuts himself shaving, the POTUS will have the same
cut, because they are one and the same person (at least for now). But in
another year or so, if Obama cuts himself, the POTUS will not notice,
because the name POTUS will have been rebound to a different person.


-- 
Steven




More information about the Python-list mailing list