Peculiar swap behavior
clp2 at rebertia.com
Tue Feb 24 00:20:45 CET 2009
On Mon, Feb 23, 2009 at 10:43 AM, Tim Chase
<python.list at tim.thechases.com> wrote:
> # swap list contents...not so much...
>>>> m,n = [1,2,3],[4,5,6]
>>>> m[:],n[:] = n,m
> ([4, 5, 6], [4, 5, 6])
#evaluate RHS. simply *take pointers* since the RHS is just plain variables
ptr_n = &n
ptr_m = &m
#perform "assignments" to LHS
#remember that x[y] = z is really a method call to __setitem__ in disguise
#let's pseudo-expand the method calls
#also remember that the assignments must be serialized (Python isn't
m._items = (*ptr_n)._items #uh-oh! this just clobbered n._items!
since we only kept a pointer to n, n._items is now gone forever!
n._items = (*ptr_m)._items #uh-oh! this now has no real effect since
we clobbered m._items
> The first two work as expected but the 3rd seems to leak some internal
> abstraction. It seems to work if I force content-copying:
>>>> m[:],n[:] = n[:],m[:]
#evaluate RHS. it's more complicated this time. this matters significantly!
#remember that x[y] is really a *method call* in disguise to __getitem__
#let's pseudo-expend the method-calls too
#note that we *make copies* instead of just taking pointers this time!
n_cpy = copy_list(n)
m_cpy = copy_list(m)
#same principles as before
m._items = n_cpy._items #but we have a copy of m._items in m_cpy, so
m._items isn't lost forever!
n._items = m_cpy._items #yay, it works!
> Is this a bug, something Python should smack the programmer for trying, or
> just me pushing the wrong edges? :)
Little from column A, little from column B. Using the swapping
assignment works slightly unintuitively with list slices because
copying doesn't magically take place; you need to do this copying
explicitly whereas it's sorta done for you with plain variable
swapping. Just keep in mind that container contents work
"by-reference" rather than "by-value", so to speak.
Follow the path of the Iguana...
More information about the Python-list