Slicing versus loops, was Re: for i in range() anti-pattern

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Thu Nov 30 07:59:45 EST 2006


On Thu, 30 Nov 2006 11:17:17 +0100, Peter Otten wrote:

> 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.

Sure. But if you have millions of items in a list, the pointers themselves
take millions of bytes -- otherwise known as megabytes.


[snip]
>> 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. 

Well, I thought about choosing an example that disproved my point, but I
couldn't think of one :-)

> 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

I always forget that extended slices can be assigned to as well as
assigned from! Nice piece of code... if only it worked.

>>> def swap_slice(items):
...     left = items[::2]
...     items[::2] = items[1::2]
...     items[1::2] = left
...     return items
...
>>> alist
[0, 1, 2, 3, 4]
>>> swap_slice(alist)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in swap_slice
ValueError: attempt to assign sequence of size 2 to extended slice of size 3

Everybody always forgets corner cases... like lists with odd number of
items... *wink*

Here is a version that handles both odd and even length lists:

def swap_slice(items):
    left = items[:len(items)-1:2]
    items[:len(items)-1:2] = items[1::2]
    items[1::2] = left
    return items


Replacing the explicit Python for loop with an implicit loop in C makes it
very much faster.


-- 
Steven.




More information about the Python-list mailing list