[Tutor] List Splicing

Lie Ryan lie.1296 at gmail.com
Thu Jun 18 20:39:03 CEST 2009


Luke Paireepinart wrote:
> Robert Berman wrote:
>> Emille,
>>
>> Thank you for the example of list splicing.  Do you know if this is 
>> faster than a more conventional loop statement as in my code for
>> primearray which is in my original post (reprinted here)
> As has been mentioned, you will want to profile your code to know what
> is truly faster.
> however, the main idea in speeding up your code is to move as much of
> the actual operations to C functions as possible.
> For example,
> x = []
> for i in range(10000):
>    x.append(0)
> 
> is going to be quite a bit slower than
> x = [0] * 10000
> 
> 
>>>> t = Timer("""x = [0] * 1000""")
>>>> t.timeit()
> 6.623384202829115
>>>> t = Timer("""x = []
> for i in range(1000):
>    x.append(0)""")
>>>> t.timeit()
> 141.14222554321785
> 
> As you can see, the for loop version is about 20 times slower than the
> other version.
> But they both accomplish the same thing.
> The key here is that the first one, using the "[] * var" syntax, does
> not iterate over items individually.
> This is a gross oversimplification, but think of the python interpreter
> like this:
> you take your code to a copy shop (a la Kinkos).  however, they do not
> have any copy machines... instead they will rewrite it by hand, line by
> line.
> and say they're going to charge you 20 cents per line.
> Therefore you'd want to minimize the lines of code to save money, right?
>

Also, it's a matter of memory allocation. With an .append loop, there is
no way python would know how much memory to allocate in advance;
therefore it has to repeatedly reallocate memory as the list grows.
Reallocating is an expensive stuff as the interpreter has to copy the
whole list everytime.

With [0] * 100, the interpreter knows to allocate a memory for 100
objects, in advance. It can allocate once and does not need to copy the
list.

But remember that all these are low level stuffs we should not need to
worry about unless we have problems with performance.

As for the original question (l1[n+n:len(l1):n] = 0), I usually use this:

l1[start:stop:step] = [value] * len(ll[start:stop:step])

Since the len(ll[start:stop:step]) part will only generate a slice
object, it would be fast. However, note that [value] * int does generate
a list. Maybe an even faster version could be made using
itertools.repeat(0, len(a[2::2])), we'll need to ask timeit's opinion
about it.



More information about the Tutor mailing list