Why do these list methods (append, sort, extend, remove, clear, reverse) return None rather than the resulting list?

I’ve noticed that many operations on lists that modify the list’s contents will return None, rather than returning the list itself. Examples:

>>> mylist = ['a', 'b', 'c']
>>> empty = mylist.clear()
>>> restored = mylist.extend(range(3))
>>> backwards = mylist.reverse()
>>> with_four = mylist.append(4)
>>> in_order = mylist.sort()
>>> without_one = mylist.remove(1)
>>> mylist
[0, 2, 4]
>>> [empty, restored, backwards, with_four, in_order, without_one]
[None, None, None, None, None, None]

What is the thought process behind this decision?

To me, it seems hampering, since it prevents “chaining” of list processing (e.g. mylist.reverse().append('a string')[:someLimit]). I imagine it might be that “The Powers That Be” decided that list comprehension is a better paradigm (a valid opinion), and so didn’t want to encourage other methods – but it seems perverse to prevent an intuitive method, even if better alternatives exist.


This question is specifically about Python’s design decision to return None from mutating list methods like .append. However, novices often write incorrect code that expects .append (in particular) to return the same list that was just modified. Please do close such questions as a duplicate of this one, however. “The code did the wrong thing because the result was None rather than the list” is something that the OP in these cases should have discovered independently via debugging; creating a proper MRE leaves behind a question like this one – therefore, it can be considered a duplicate.

See How can I collect the results of a repeated calculation in a list, dictionary etc. (or make a copy of a list with each element modified)? for the simple question of “how do I append to a list repeatedly?” (or debugging questions that boil down to that problem). This is a new canonical that has been specifically prepared to address the topic with the perspective that beginners lack.

To get modified versions of the list, see:

  • How to allow list append() method to return the new list
  • How can I get a sorted copy of a list?
  • How do I concatenate two lists in Python? (to replace .extend)
  • A quick way to return list without a specific element in Python (to replace .remove)
  • How can I get a reversed copy of a list (avoid a separate statement when chaining a method after .reverse)?

The same issue applies to some methods of other built-in data types, e.g. set.discard (see How to remove specific element from sets inside a list using list comprehension) and dict.update (see Why doesn’t a python dict.update() return the object?).

The same reasoning applies to designing your own APIs. See Is making in-place operations return the object a bad idea?.

5

The general design principle in Python is for functions that mutate an object in-place to return None. I’m not sure it would have been the design choice I’d have chosen, but it’s basically to emphasise that a new object is not returned.

Guido van Rossum (our Python BDFL) states the design choice on the Python-Dev mailing list:

I’d like to explain once more why I’m so adamant that sort() shouldn’t
return ‘self’.

This comes from a coding style (popular in various other languages, I
believe especially Lisp revels in it) where a series of side effects
on a single object can be chained like this:

x.compress().chop(y).sort(z)

which would be the same as

x.compress()
x.chop(y)
x.sort(z)

I find the chaining form a threat to readability; it requires that the
reader must be intimately familiar with each of the methods. The
second form makes it clear that each of these calls acts on the same
object, and so even if you don’t know the class and its methods very
well, you can understand that the second and third call are applied to
x (and that all calls are made for their side-effects), and not to
something else.

I’d like to reserve chaining for operations that return new values,
like string processing operations:

y = x.rstrip("n").split(":").lower()

There are a few standard library modules that encourage chaining of
side-effect calls (pstat comes to mind). There shouldn’t be any new
ones; pstat slipped through my filter when it was weak.

4

I can’t speak for the developers, but I find this behavior very intuitive.

If a method works on the original object and modifies it in-place, it doesn’t return anything, because there is no new information – you obviously already have a reference to the (now mutated) object, so why return it again?

If, however, a method or function creates a new object, then of course it has to return it.

So l.reverse() returns nothing (because now the list has been reversed, but the identfier l still points to that list), but reversed(l) has to return the newly generated list because l still points to the old, unmodified list.

EDIT: I just learned from another answer that this principle is called Command-Query separation.

4

One could argue that the signature itself makes it clear that the function mutates the list rather than returning a new one: if the function returned a list, its behavior would have been much less obvious.

2

If you were sent here after asking for help fixing your code:

In the future, please try to look for problems in the code yourself, by carefully studying what happens when the code runs. Rather than giving up because there is an error message, check the result of each calculation, and see where the code starts working differently from what you expect.

If you had code calling a method like .append or .sort on a list, you will notice that the return value is None, while the list is modified in place. Study the example carefully:

>>> x = ['e', 'x', 'a', 'm', 'p', 'l', 'e']
>>> y = x.sort()
>>> print(y)
None
>>> print(x)
['a', 'e', 'e', 'l', 'm', 'p', 'x']

y got the special None value, because that is what was returned. x changed, because the sort happened in place.

It works this way on purpose, so that code like x.sort().reverse() breaks. See the other answers to understand why the Python developers wanted it that way.

To fix the problem

First, think carefully about the intent of the code. Should x change? Do we actually need a separate y?

Let’s consider .sort first. If x should change, then call x.sort() by itself, without assigning the result anywhere.

If a sorted copy is needed instead, use y = x.sorted(). See How can I get a sorted copy of a list? for details.

For other methods, we can get modified copies like so:

.clear -> there is no point to this; a “cleared copy” of the list is just an empty list. Just use y = [].

.append and .extend -> probably the simplest way is to use the + operator. To add multiple elements from a list l, use y = x + l rather than .extend. To add a single element e wrap it in a list first: y = x + [e]. Another way in 3.5 and up is to use unpacking: y = [*x, *l] for .extend, y = [*x, e] for .append. See also How to allow list append() method to return the new list for .append and How do I concatenate two lists in Python? for .extend.

.reverse -> First, consider whether an actual copy is needed. The built-in reversed gives you an iterator that can be used to loop over the elements in reverse order. To make an actual copy, simply pass that iterator to list: y = list(reversed(x)). See How can I get a reversed copy of a list (avoid a separate statement when chaining a method after .reverse)? for details.

.remove -> Figure out the index of the element that will be removed (using .index), then use slicing to find the elements before and after that point and put them together. As a function:

def without(a_list, value):
    index = a_list.index(value)
    return a_list[:index] + a_list[index+1:]

(We can translate .pop similarly to make a modified copy, though of course .pop actually returns an element from the list.)

See also A quick way to return list without a specific element in Python.

(If you plan to remove multiple elements, strongly consider using a list comprehension (or filter) instead. It will be much simpler than any of the workarounds needed for removing items from the list while iterating over it. This way also naturally gives a modified copy.)


For any of the above, of course, we can also make a modified copy by explicitly making a copy and then using the in-place method on the copy. The most elegant approach will depend on the context and on personal taste.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật