-2

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.

Bryan Hunt
  • 3,685
  • 2
  • 24
  • 36

4 Answers4

5

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])
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
  • argh, I'm trying to squeeze it all into a lambda function. Is there a way to avoid creating an intermediate variable? – Bryan Hunt Mar 08 '12 at 12:53
  • @BryanHunt stop trying to squeeze it into a lambda: just use a named function, you lose nothing. – Duncan Mar 08 '12 at 12:57
  • Comparing it with Scala code, this wikipedia page made me do it http://en.wikipedia.org/wiki/Fold_(higher-order_function)#Folds_in_various_languages I want to create a frequency plot with matplotlib – Bryan Hunt Mar 08 '12 at 13:00
3

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.

Zsolt Botykai
  • 50,406
  • 14
  • 85
  • 110
samfrances
  • 3,405
  • 3
  • 25
  • 40
  • 2
    The idea behind this behavior is called Command-Query-Separation (e.g. http://martinfowler.com/bliki/CommandQuerySeparation.html) – stephan Mar 08 '12 at 12:57
1

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]
wRAR
  • 25,009
  • 4
  • 84
  • 97
0

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.

octern
  • 4,825
  • 21
  • 38