Improve the API of list and tuple

  1. list has an index method but not a find method while str has both index and find methods. Since str is essentially an array of characters, it makes sense to make a list support the find method.
  2. People often refer to tuple as the immutable version of list. However, tuple does not have many of the methods that list have especially those that won’t change the list/tuple. For example, it makes sense to make tuple support rindex since it already has an index method.
1 Like

What’s wrong with list.index()? If the difference is an issue, I’d argue we should remove str.find() altogether instead of adding list.find().

And they are wrong. The solution to people’s difficulties in using tuple as an immutable list is to tell them to stop doing that, not make tuple an immutable list.

Here are the methods that lists support, I have divided them into two
groups: those that mutate (modify) the list, and those that don’t:

# Mutator methods
append, clear, extend, insert, pop, remove, reverse, sort

# Non-mutator methods
copy, count, index

The first group don’t make sense for tuples, because they are immutable.
Here are the methods that tuple supports:

count, index

The only method missing is copy, but because tuples are immutable, you
don’t really need to make a copy. But if you don’t, you can use slicing:

new = old[:]

or the copy module to make a copy of the tuple and all its items:

new = copy.deepcopy(old)

Here are a list of the operators that lists support:

len() < <= >= == != in + (concatenation) * (repetition)

Tuples support exactly the same operators.

Lists support item getting, setting and deleting:

L[position]          # get
L[position] = value  # set
del L[position]      # delete

Since tuples are immutable, they only support item getting.

Apart from copy(), which is not needed, what list methods are
missing from tuple?

Sorry, my bad. I though list has the rindex method but it doesn’t. Then it is lisst/tuple missing methods rindex, find and rfind. Those methods are present in the str class.

Note that str.index() and list.index() have different semantic.

>>> '1234'.index('23')
1
>>> [1, 2, 3, 4].index([2, 3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: [2, 3] is not in list
1 Like

Strings have lots of methods that lists and tuples don’t have. Why are
rindex, find and rfind necessary for them?

I have been using Python for nearly 25 years, and I have not once needed
list or tuple rindex. When would you use it?

The difference between str.find and str.index is very small. If Python
was being designed today, probably only str.index would be used. The
problem with str.find is that it is too easy to write buggy code that
silently does the wrong thing:

# Remove the first # sign and everything after it
mystring = mystring[:mystring.find("#")]

Can you see the bug? Is it obvious that this line is buggy? I would
say no, because I have written buggy code like that dozens of times. So
when the bug hits, my code silently does the wrong thing, and then I
have to debug a problem where I have no idea what caused it. The bug
could be anywhere in my code!

But if I use index instead:

mystring = mystring[:mystring.index("#")]

then when the bug hits, I get an immediate exception that points to the
exact line that is buggy.

And I believe Guido once said that we wouldn’t have find() in strings if we were to do it again and instead just have index().

1 Like