37

Is there a reason being list.append evaluating to false? Or is it just the C convention of returning 0 when successful that comes into play?

>>> u = []
>>> not u.append(6)
True
Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
diciu
  • 29,133
  • 4
  • 51
  • 68

7 Answers7

45

Most Python methods that mutate a container in-place return None -- an application of the principle of Command-query separation. (Python's always reasonably pragmatic about things, so a few mutators do return a usable value when getting it otherwise would be expensive or a mess -- the pop method is a good example of this pragmatism -- but those are definitely the exception, not the rule, and there's no reason to make append an exception).

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
20

None evaluates to False and in python a function that does not return anything is assumed to have returned None.

If you type:

>> print u.append(6)
None

Tadaaam :)

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • 6
    Mutators (like append, extend, sort, etc.) which update a list do not return a value. – S.Lott Nov 05 '09 at 18:41
  • `None` doesn't *evaluate* to `False`. – SwiftsNamesake Nov 19 '16 at 14:23
  • @SwiftsNamesake Try `bool(None)` – Chris_Rands Feb 15 '17 at 09:49
  • @Chris_Rands `None` is not a boolean, which is why you need the `bool` function to convert it (done implicitly by `not`). Yes, I know it's a quibble but it's `True`. – SwiftsNamesake Feb 15 '17 at 10:18
  • @SwiftsNamesake No-one said `None` is a boolean, but it does evaluate to `False` – Chris_Rands Feb 15 '17 at 10:33
  • @Chris_Rands I guess my quibble is with the phrase *evaluates to*, which admittedly is due to the OP. As I said I don't dispute the gist of the answer (who would) and I know that `None` is 'falsy'. – SwiftsNamesake Feb 15 '17 at 10:40
  • @SwiftsNamesake: I am open to suggestions, *evaluates* remains the best expression I have so far. – Matthieu M. Feb 15 '17 at 10:45
  • 1
    @SwiftsNamesake I find *evaluates* clearer than Python's own semantics, `help(bool)` says "bool(x): Returns True when the argument x is true". But `x` is true seems too similar to `x is True`, which of course has a completely different meaning – Chris_Rands Feb 15 '17 at 11:00
7

because .append method returns None, therefore not None evaluates to True. Python on error usually raises an error:

>>> a = ()
>>> a.append(5)
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    a.append(5)
AttributeError: 'tuple' object has no attribute 'append'
SilentGhost
  • 307,395
  • 66
  • 306
  • 293
5

It modifies the list in-place, and returns None. None evaluates to false.

Matt Anderson
  • 19,311
  • 11
  • 41
  • 57
3

Actually, it returns None


>>> print u.append(6)
None
>>> print not None
True
>>> 

adam
  • 6,582
  • 4
  • 29
  • 28
1

Method append modifies the list in-place and the return value None

In your case, you are creating an array — [6] — on the fly, then discarding it. The variable b ends up with the return value of None.

Why?
This comply with the principle of Command–query separation devised by Bertrand Meyer.
It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In your example:

u.append(6)

append modified the state of [], so it’s not a best practice to return a value compliance with the principle.

In theoretical terms, this establishes a measure of sanity, whereby one can reason about a program's state without simultaneously modifying that state.

CQS is well-suited to the object-oriented methodology such as python.

AbstProcDo
  • 19,953
  • 19
  • 81
  • 138
0

The list.append function returns None. It just adds the value to the list you are calling the method from.

Here is something that'll make things clearer:

>>> u = []
>>> not u
False
>>> print(u.append(6)) # u.append(6) == None
None    
>>> not u.append(6) # not None == True
True
Rafael Aguilar
  • 3,084
  • 1
  • 25
  • 31