[Python-ideas] add a list.swap() method

Raymond Hettinger python at rcn.com
Wed Jun 24 00:02:18 CEST 2009


[Kristján Valur Jónsson]
> The idea is to speed up the swapping of list elemenst so that
>     a.swap(b)
> is equivalent to
>    a[:], b[:] = b[:], a[:]
> but without all the overhead of creating slices, assigning them and so forth.

The technique is useful and very fast.  I used something similar in setobject.c
in the set_swap_bodies() function, but it was sufficiently dangerous to
subclass invariants that it was not exposed to the end-user.

Subclasses written as C extensions are the most in danger because a
swap could break their internal invariants and possibly crash the code.
Pure python list subclasses are only in danger of breaking without crashing.

While Python is a consenting adults language, I think the basic objects
like lists should be kept free of dangerous or hard-to-use constructs.

The problem with the OP's example is that it only makes sense in interactions
between a list and a list subclass that won't be broken by it.  For straight
list-to-list interactions, it is better to write "a,b = b,a" (though this is
not exactly the same thing since the identity of a and b will change,
not just their contents).  For list subclass uses (a more advanced topic),
some example will work and some won't (I gave two failing examples in the
tracker discussion).  When the list subclass is a C extension written by a
third-party, it may not be possible to know whether or not a swap
will break invariants.  That's a killer.

There are a number of places in the language where swapping could
be used (frozenset to set conversions for example) but the technique
is fragile and probably should not become part of the language as
distributed.

In the OP's use case, it is not hard to build a C extension for his subclasses
and include a swap() method there.  That is a much less fragile design because
the subclass already knows about its own internal invariants and it can
verify that its input source is an exact list.  An OOP design principle is that a
method should be added to the class that has the most knowledge about
all of the inputs (in this case, the C extension subclass knows more than
general purpose lists).   A side benefit of this design (putting swap() in the
list subclass instead of standard list objects) is that this avoids
putting dangerous optimizations in the hands of beginning users (i.e. it
keeps the list API simple and clean).


Raymond







More information about the Python-ideas mailing list