[Python-ideas] Python Enhancement Proposal for List methods

Terry Reedy tjreedy at udel.edu
Sun Oct 21 16:58:00 EDT 2018


On 10/21/2018 9:00 AM, Siva Sukumar Reddy wrote:

> I am really new to Python contribution community want to propose below 
> methods for List object.

For most classes, there is an infinite number of possible functions that 
could be made into methods.  The Python philosophy is to include as 
methods the basic functions needed to write other functions.  So number 
classes include the basic operations of +, -, *, /, and ** as methods. 
The math and cmath modules contain number functions that use these basic 
operations.

The list class also has a fairly small set of methods.  Nearly all are 
either original or were added before list.pop, about 20 years ago. 
list.clear was added more recently, in analogy with dict.clear, and 
there was some opposition because there are other ways to clear a list.

> 1. *list.replace( item_to_be_replaced, new_item )*: which replaces all 
> the occurrences of an element in the list instead of writing a new list 
> comprehension in place.
> 2. *list.replace( item_to_be_replaced, new_item, number_of_occurrences 
> )*: which replaces the occurrences of an element in the list till 
> specific number of occurrences of that element. The 
> number_of_occurrences can defaulted to 0 which will replace all the 
> occurrences in place.

I presume these are somewhat in analogy with str.replace(old, new, 
count=-1), except for being limited to one sequence member and being 
done in place.  Note that only 1 method is needed and the default count 
should be -1, not 0.

However, the need for a built-in method is much, much less.  Nearly all 
cases that need to be done inline code can be done like this.

for i, item in enumerate(mylist):
     if item == old:
         mylist[i] = new

As Serhiy noted from previous discussion, other conditions are possible, 
such as 'item in {old1, old2, old3}' or, given a list of numbers,
     if item > max: mylist[i] = max

> 3. *list.removeall( item_to_be_removed )*: which removes all the 
> occurrences of an element in a list in place.

str.replace(old, '') does this (not in place) for strings.  There are 
also str.translate and re.sub and re.subn.

An indefinite number of in-place removes is a generally a bad idea 
unless done carefully.
alist.remove is inherently O(n).
alist.removeall implemented naively would be O(n*n)/
alist = [x for x in alist if x == old] or
alist = list(x for x in alist if x == old) or
alist = list(filter(lambda x: x == old)) is O(n).

Again, as Serhiy noted, 'x == old' is only one possible condition.

The last example illustrates another point.  In Python 3, one can 
usually and often should avoid turning streams of objects into a 
concrete list until one needs one of the particular list operations.

I noted above that we have only added 1 list method (that I know of) 
since .pop.  On the other hand, we added generators and then the 
itertools module with multiple basic functions and multiple recipes 
based on those functions.  Since lists are no longer the basic 
representation of sequences of items, adding list methods is somewhat 
obsolete.

If possible, it is best to filter out multiple items when creating the 
list instead of later.  Or to put it another way, it is best to avoid 
turning a stream into a list for as long as possible.  If space and 
aliasing are not issues, replacing a list is easier and possibly faster 
that editing it in place.  Note that editors for adding, replacing, and 
deleting items tend to use tree structures rather than a single linear 
sequence.

An alternative to removing items is to replace them with a null value, 
such as None, '', 0, 1 (for multiplication), 'pass' (for code 
execution), or sentinal=object().  The choice depends on what is to be 
done later.  In fact, temporary replacement is the key to efficient 
multiple removals.

-- 
Terry Jan Reedy



More information about the Python-ideas mailing list