[Tutor] Standard way to append to a list? ['+=' is in-place
concatenation]
Danny Yoo
dyoo@hkn.eecs.berkeley.edu
Wed Apr 16 21:00:02 2003
On Thu, 17 Apr 2003, Magnus [iso-8859-1] Lyck=E5 wrote:
> Secondly, using "l =3D l + [4]" or the shorter form "l +=3D [4]", you are
> doing the following:
>
> 1. To start with, you have a list object containing [1,2,3]
> 2. Then you create a new list object containing [4].
> 3. With your assignment you create a new list object, and
> place the sum of the two lists, i.e. [1,2,3,4] in that.
> 4. As you rebind the variable name "l" from the list
> containing [1,2,3] to the one containing [1,2,3,4], you
> will reduce the reference count on the list containing
> [1,2,3]. If no other variables etc references that list,
> it will be garbage collected now (or perhaps a little
> later if you are running Jython.)
> 5. The list containing [4] will also be garbage collected as
> soon as the assignment is done.
Hi Magnus,
Clarification on the second form: the expression:
l +=3D [4]
is called an 'in-place concatenation', and for lists, this actually calls
the extend() method! For those with a C bent, here's the relevant code
from the Python source:
/***/
static PyObject *
list_inplace_concat(PyListObject *self, PyObject *other)
{
other =3D PySequence_Fast(other, "argument to +=3D must be iterable=
");
if (!other)
return NULL;
if (listextend_internal(self, other) < 0)
return NULL;
Py_INCREF(self);
return (PyObject *)self;
}
/***/
Wait a minute... I can't seem to prove this by overriding the extend()
method!
###
>>> class mylist(list):
=2E.. def extend(self, other):
=2E.. print "I'm extend()!"
=2E.. list.extend(self, other)
=2E..
>>> l =3D mylist([1, 2, 3])
>>> l +=3D [4]
>>> l
[1, 2, 3, 4]
>>> l.extend([4])
I'm extend()!
###
Weird! I'm using Python 2.2.1 here; can anyone confirm if this is
happening with Python 2.2.2 or 2.3alpha? Does this look like a bug to
anyone else? ... Checking SourceForge... nope, I don't see anything about
this.
Sorry for getting sidetracked... *grin* I'd better check that in my spare
time.
Anyway the 'in-place concatenation' statement,
left_hand_side +=3D right_hand_size
is not just syntactic sugar for
left_hand_side =3D left_hand_side + right_hand_size
Python often does take advantage of the fact that the left hand side is
being mutated.
Hope this helps!