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:27:05 EDT 2016


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

> On 24/03/2016 13:50, Steven D'Aprano wrote:
>> On Thu, 24 Mar 2016 02:24 pm, Chris Angelico wrote:
>>
>>
>>> This is how you're currently evaluating Python. Instead of starting
>>> with the most simple and obvious code
>>
>> One problem is that what counts as "simple and obvious" depends on what
>> you are used to. Coming from a background of Pascal, iterating over a
>> list like this:
>>
>> for i in range(len(mylist)):
>>      print mylist[i]
>>
>> was both simple and obvious. It took me years to break myself of that
>> habit.
>>
>> Likewise clearing a list:
>>
>> for i in range(len(mylist)-1, -1, 0):
>>      del mylist[i]
> 
> That's wouldn't be I'd call clearing a list, more like destroying it
> completely!

No, the list still exists, and mylist (the name) is still bound to it. It is
just an empty list (length zero).


> How would you actually clear a list by traversing it (ie. not just
> building a new one)?

The two "right ways" of clearing a list (i.e. setting it to an empty list)
is to use slice assignment:

mylist[:] = []

or call the mylist.clear() method.


> This doesn't work:
> 
>    for x in L:
>       x=0
> 
> as each x only refers to the value in each element of L, not the element
> itself (like the pass-by-reference problem).

Correct, except I wouldn't call it a problem. That's just not how Python
semantics work. I only know of a handful of languages that support
pass-by-reference:

Pascal
C++
Visual Basic
Some other Basics (maybe? I'm not sure)
Algol (actually pass-by-name)

 
> I'd presumably have to do:
> 
>   for i in range(len(L)):
>     L[i]=0

I wouldn't describe that as "clearing the list". It is merely setting the
existing values to some known quantity which happens to be zero. Why zero?
Why not None, or 99, or float("nan")? (Don't answer that, it's a rhetorical
question.)

In any case, I would expect that the most efficient way to set all the list
values to a particular value would be:

mylist[:] = [0]*len(mylist)

Let's find out. On my computer, using Python 3.3:


py> mylist = list(range(100000))
py> with Stopwatch():
...     mylist[:] = [0]*len(mylist)
...
time taken: 0.005215 seconds


Compared to:

py> mylist = list(range(100000))
py> with Stopwatch():
...     for i in range(len(mylist)):
...             mylist[i] = 0
...
time taken: 0.037431 seconds



That's a difference of about an order of magnitude.


The Stopwatch function used for timing is very nearly the same as the recipe
posted here:

https://code.activestate.com/recipes/577896-benchmark-code-with-the-with-statement/



-- 
Steven




More information about the Python-list mailing list