[Python-ideas] suggestion about the sort() function of the list instance

Terry Reedy tjreedy at udel.edu
Wed Mar 1 16:42:34 EST 2017


On 3/1/2017 12:26 PM, Stéfane Fermigier wrote:

> What I wanted to point out is that the paragraph quoted by Stephan ("In
> general in Python (and in all cases in the standard library) a method
> that mutates an object will return None to help avoid getting the two
> types of operations confused. So if you mistakenly write y.sort()
> thinking it will give you a sorted copy of y, you’ll instead end up with
> None, which will likely cause your program to generate an easily
> diagnosed error.") doesn't seem to be true in this case.

What is true AFAIK, is that stdlib collection mutation methods never 
return 'self'. There is usually no need to return self as one will 
already have a reference to the collection.

A disadvantage (to some) of this policy is to not be able to chain calls 
so neatly.  (But Python is not about writing everything as one-line 
expressions.)

An advantage of not returning 'self' when mutating is the possibility of 
returning something from the collection without resorting to returning 
tuples.  While most mutation methods return None, there are exceptions 
where the primary purpose of the mutation is to return something other 
than self and None.  The two that come to mind are various 
mutable_collection.pop methods (sometimes with a suffix) and 
iterator.__next__ ('pop front').  Note that an iterator is a mutable 
virtual collection, which may or may not be dependent on a concrete 
collection object that is not mutated by the iteration.

In functional languages, iteration through a sequence 'alist' may be 
done something as follows, with pair assignment.

a_it = alist
while a_it:
     a, a_it = first(a_it), rest(a_it)
     process(a)

To be time efficiency, a_list must be a linked list, so that all 
tail-slices (returned by rest), already exist.  While this can be done 
in Python, I generally prefer Python's iteration protocol.  The closest 
equivalent to the above is the admittedly clumsy

a_it = iter(alist)
while True:
     try:
         a = next(a_it)
     except StopIteration:
         break
     process(a)

But with the boilerplate code hidden, this becomes one of Python's gems.

for a in alist:
     process(a)

The above works for iterable linked lists but is MUCH more flexible and 
general.

-- 
Terry Jan Reedy




More information about the Python-ideas mailing list