0

When inserting to a negative index (negative indexes for list is impossible, i think?), or inserting far beyond the current index, list.insert does not produce IndexError, instead it just silently ignores the index and pretend you called list.append() instead, why? I expected both of these to generate IndexErrors

l = list()
l.insert(999, 999)  # expected index error because the highest valid index is 0, not 999?
l.insert(-999, -999)  # expected index error because negative indexes are impossible?
print(l)  # prints [-999, 999]

but instead of they just act as if i had written

l = list()
l.append(999)
l.append(-999)

why?

wjandrea
  • 28,235
  • 9
  • 60
  • 81
hanshenrik
  • 19,904
  • 4
  • 43
  • 89
  • *"negative indexes for list is impossible, i think?"* -- Did you try it? `[1, 2, 3][-1]` -> `3`. They index the list in reverse. (But to be clear, this is incidental to your question.) – wjandrea May 07 '22 at 18:28
  • "negative indexes for list is impossible, i think?" You have ten years experience with this web site, multiple gold badges, 80 questions and nearly a thousand answers; you should understand the [research expectations](https://meta.stackoverflow.com/questions/261592) here by now. It takes trivial effort to find the [relevant documentation](https://docs.python.org/3/tutorial/datastructures.html). – Karl Knechtel May 07 '22 at 18:37
  • `l.append(-999)` would result in `[999, -999]`. I think you meant `l.insert(0, -999)`. – wjandrea May 07 '22 at 18:37
  • @wjandrea it is not really incidental. The code works for the same reason that the negative list indexes work, and in the same way; the invariant "`x[i]` is equivalent to `x[len(x) + i]`, for `-len(x) <= i < 0`" is preserved this way. (This should also be covered in any decent tutorial, though perhaps not as explicitly as I'd like.) – Karl Knechtel May 07 '22 at 18:38
  • 1
    @Karl What OP's actually asking is, why does `list.insert()` allow an index that's **out of range**? OP thinks the range is `range(0, len(x))` when it should be `range(-len(x), len(x))`, but that's beside the point. – wjandrea May 07 '22 at 18:46
  • 1
    Oh. In that case there are two questions that have to be disentangled, I guess. The other answer is that it is to preserve the invariant "`x.insert(a, b)` is equivalent to `x[a:a] = b`". Out-of-range indices are accepted for slices. – Karl Knechtel May 07 '22 at 18:54

1 Answers1

1

This is expected. See https://github.com/python/cpython/blob/main/Objects/listobject.c#L280-L286

if (where < 0) {
    where += n;
    if (where < 0)
        where = 0;
}
if (where > n)
    where = n;

where where is the index.

Dilara Gokay
  • 418
  • 3
  • 10