Python, is this a bug, append to a list within a tuple results in None?

Question:

This is one of the shortest examples I’ve written in a long time

I create and update a tuple3

In [65]: arf=(0,1,[1,2,3])

In [66]: arf=(arf[0],arf[1], arf[2] )

In [67]: arf
Out[67]: (0, 1, [1, 2, 3])

So the reassignment worked.

Now I try to change it’s contents.

In [69]: arf=(arf[0],arf[1], [2] )

In [70]: arf
Out[70]: (0, 1, [2])

In [71]: arf=(arf[0],arf[1], arf[2].append(3) )

In [72]: arf
Out[72]: (0, 1, None)

I get back None??? Hey, what gives? Sorry I’m a python noob.

Asked By: Bryan Hunt

||

Answers:

list.append() always returns None

so arf[2].append(3) will append 3 to arf and return None

you never get to see this change to arf[2] because you are immediately rebinding arf to the newly created tuple

Perhaps this is what you want

arf = (arf[0], arf[1], arf[2]+[3])
Answered By: John La Rooy

The list.append method changes the list in place and returns None. This isn’t a bug, this is just how the append method works.

Answered By: samfrances

append doesn'[t return the new list, it modifies the old one in-place:

>>> a = [1, 2, 3]
>>> b = a.append(4)
>>> print b
None
>>> print a
[1, 2, 3, 4]
Answered By: wRAR

To elaborate on gnibbler’s answer, list.append() changes the list itself, but it doesn’t return the new value of the list. It returns None. So your command 71 changes the value of arf[2] in the way you wanted, but then it immediately returns None and sets arf[2] to that.

The self-reference in your example obfuscates things a bit, but if you try a command like someothervariable=arf[2].append(3), you’ll see how it works. someothervariable is set to None and arf[2] has 3 appended without an explicit assignment statement.

Answered By: octern