6

Today I spent about 20 minutes trying to figure out why this worked as expected:

users_stories_dict[a] = s + [b] 

but this would have a None value:

users_stories_dict[a] = s.append(b)

Anyone know why the append function does not return the new list? I'm looking for some sort of sensible reason this decision was made; it looks like a Python novice gotcha to me right now.

Jakub Hampl
  • 39,863
  • 10
  • 77
  • 106
worker1138
  • 2,071
  • 5
  • 29
  • 36
  • 1
    `append()` is not documented as returning a value. What caused you to think it did? Where did you get the idea that append returns a value? What documentation where you reading that suggested such a thing? – S.Lott Apr 08 '11 at 02:33
  • `users_stories_dict[a].extend(b)` btw – Jochen Ritzel Apr 08 '11 at 02:54
  • @Jochen: `users_stories_dict[a].extend(b)` would only work if `b` is an iterable. Assuming `b` is a string, compare `a_list.append(b)` and `a_list.extend(b)`. BTW, `list.extend()` also returns `None` just like `list.append()`. – tzot May 01 '11 at 15:11
  • @S.Lott to be fair, in functional programming languages, where list()s are immutable, `.append()` returns a new list. its not an unreasonable assumption. – rbp Jan 15 '16 at 16:31

2 Answers2

12

append works by actually modifying a list, and so all the magic is in side-effects. Accordingly, the result returned by append is None. In other words, what one wants is:

s.append(b)

and then:

users_stories_dict[a] = s

But, you've already figured that much out. As to why it was done this way, while I don't really know, my guess is that it might have something to do with a 0 (or false) exit value indicating that an operation proceeded normally, and by returning None for functions whose role is to modify their arguments in-place you report that the modification succeeded.

But I agree that it would be nice if it returned the modified list back. At least, Python's behavior is consistent across all such functions.

  • 7
    I think it's really useful to make it clear to the programmer/reader which functions are mutating data. For instance, it would be extremely unfortunate to have a = b.sort() sort b when you didn't expect it to. – Mike Axiak Apr 08 '11 at 02:17
  • 3
    The reason why `list.append` returns `None` is the “Command-query separation” principle, as Alex Martelli says [here](http://stackoverflow.com/questions/1682567#1682601). – tzot May 01 '11 at 15:21
9

The append() method returns a None, because it modifies the list it self by adding the object appended as an element, while the + operator concatenates the two lists and return the resulting list

eg:

a = [1,2,3,4,5]
b = [6,7,8,9,0]

print a+b         # returns a list made by concatenating the lists a and b
>>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

print a.append(b) # Adds the list b as element at the end of the list a and returns None
>>> None

print a           # the list a was modified during the last append call and has the list b as last element
>>> [1, 2, 3, 4, 5, [6, 7, 8, 9, 0]]

So as you can see the easiest way is just to add the two lists together as even if you append the list b to a using append() you will not get the result you want without additional work

P2bM
  • 1,038
  • 6
  • 9