0

I have list that contains some repeatable elements.
And I want to find the index of the element starting from specific position (not from the start).
So I used index method on list object. According to documentation it has optional parameters start and stop.

Example of code I use:

lst = [5, 1, 2, 3, 4, 5, 6, 7]
index_5 = lst.index(5, start=2)
print(index_5)

And when I ran this code I got exception that index method doesn't have parameter start. What could be the problem?

Traceback (most recent call last):
  File "D:/Misc.py", line 2, in <module>
    index_5 = lst.index(5, start=2)
TypeError: index() takes no keyword arguments

As workaround I could make trick below, but if there's way to use language feature, I'd prefer it.

index_5 = lst[2:].index(5) + 2
Aleks Lee
  • 136
  • 1
  • 1
  • 10
  • 1
    The parameters are probably positional-only. Have you tried `index(5, 2)`? – N Chauhan Dec 21 '19 at 11:47
  • Yes, you're right. Thank you. It works this why. But signature in builtins.py specified as ```def index(self, value, start=None, stop=None)``` so I expected that it is named parameters. – Aleks Lee Dec 21 '19 at 11:51
  • @AleksLee, the `start` and `stop` seem to be there for optimizing list search, but do not modify the `return` value – ksha Dec 21 '19 at 11:57
  • 1
    Which part of the documentation are you refering to? https://docs.python.org/3/library/stdtypes.html#common-sequence-operations describes it as `s.index(x[, i[, j]])`, and so doesn't mention keyword arguments. – Thierry Lathuille Dec 21 '19 at 12:02
  • If you are refering to [this part of the tutorial](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists), note the difference in syntax between methods that take positional arguments, like `list.index(x[, start[, end]])` where `start` and `end` are just placeholders for your values, and the ones with keyword arguments, who look like: `list.sort(key=None, reverse=False)` – Thierry Lathuille Dec 21 '19 at 12:17
  • I checked signature in builtins.py: `def index(self, value, start=None, stop=None)`, so expected to use keyword argument. Thank you, now I understand. – Aleks Lee Jan 05 '20 at 17:59

2 Answers2

0

As per the documentation for index, parameter start only narrows down the search space:

The optional arguments start and end are interpreted as in the slice notation and are used to limit the search to a particular subsequence of the list. The returned index is computed relative to the beginning of the full sequence rather than the start argument.

Beside the error says no keyword arguments, so you should use positional arguments.

ksha
  • 2,007
  • 1
  • 19
  • 22
0

But signature in builtins.py specified as def index(self, value, start=None, stop=None) so I expected that it is named parameters.

See this answer. It says:

Due to the way the Python C-level APIs developed, a lot of built-in functions and methods don't actually have names for their arguments. Even if the documentation calls the argument default, the function doesn't recognize the name default as referring to the optional second argument. You have to provide the argument positionally.

The documentation has been poor on positional only parameters before, but on modern Python, they're improving. The key info is the seemingly out of place / in the signature:

index(value, start=0, stop=9223372036854775807, /)
                                                ^ This is not a typo!

That means that all arguments prior to the forward slash are positional only, they can't be passed by keyword.

A slash in the argument list of a function denotes that the parameters prior to it are positional-only. Positional-only parameters are the ones without an externally-usable name. Upon calling a function that accepts positional-only parameters, arguments are mapped to parameters based solely on their position.

Try this:

lst.index(5,2)

As for explanation, this could also explain it:

Many of the builtin functions use only METH_VARARGS which means they don't support keyword arguments. "len" is even simpler and uses an option METH_O which means it gets a single object as an argument. This keeps the code very simple and may also make a slight difference to performance.

abhiarora
  • 9,743
  • 5
  • 32
  • 57