Slicing versus loops, was Re: for i in range() anti-pattern
Peter Otten
__peter__ at web.de
Thu Nov 30 05:17:17 EST 2006
Steven D'Aprano wrote:
> And remember that if alist is truly huge, you may take a performance hit
> due to duplicating all those megabytes of data when you slice it.
Having the same object in two lists simultaneously does not double the total
amount of memory; you just need space for an extra pointer.
> If you
> are modifying the original, better to skip making a slice.
>
> I wrote a piece of code the other day that had to walk along a list,
> swapping adjacent elements like this:
>
> for i in xrange(0, len(alist)-1, 2):
> alist[i], alist[i+1] = alist[i+1], alist[i]
>
>
> The version using enumerate is no improvement:
>
> for i, x in enumerate(alist[0:len(alist)-1:2]):
> alist[i*2], alist[i*2+1] = alist[i*2+1], x
>
>
> In my opinion, it actually is harder to understand what it is doing.
> Swapping two items using "a,b = b,a" is a well known and easily recognised
> idiom. Swapping two items using "a,b = b,c" is not.
That example was chosen to prove your point. The real contender for the
"swap items" problem are slices.
def swap_slice(items):
left = items[::2]
items[::2] = items[1::2]
items[1::2] = left
return items
def swap_loop(items):
for i in xrange(0, len(items)-1, 2):
k = i+1
items[i], items[k] = items[k], items[i]
return items
$ python2.5 -m timeit -s 'from swap import swap_loop as swap; r =
range(10**6)' 'swap(r)'
10 loops, best of 3: 326 msec per loop
$ python2.5 -m timeit -s 'from swap import swap_slice as swap; r =
range(10**6)' 'swap(r)'
10 loops, best of 3: 186 msec per loop
$ python2.5 -m timeit -s 'from swap import swap_loop as swap; r =
range(10**7)' 'swap(r)'
10 loops, best of 3: 3.27 sec per loop
$ python2.5 -m timeit -s 'from swap import swap_slice as swap; r =
range(10**7)' 'swap(r)'
10 loops, best of 3: 2.29 sec per loop
With 10**7 items in the list I hear disc access on my system, so the
theoretical sweet spot where swap_slice() is already swapping while
swap_loop() is not may be nonexistent...
Peter
More information about the Python-list
mailing list