почему список индексов вне диапазона, но кажется, что все в порядке

#python-3.x

#python-3.x

Вопрос:

Почему я получил «индекс списка вне диапазона», когда пытался запустить этот код

 x = 20
l = [[] for i in range(0, x)]
for m in range(x):
    for i in range(len(l)):
        if i != len(l):
            l[i 1].append(m)
  

Комментарии:

1. не следует ли if i != len(l): решить эту проблему?

2. хорошо, я думаю, я понял

Ответ №1:

for i in range(len(l)): выдает 0 len(l) - 1 включительно. So i никогда не равно len(l) , но когда оно равно len(l) - 1 , l[i 1] пытается получить доступ l[len(l)] к тому, что на единицу больше, чем самый высокий разрешенный индекс в l ( list индексы a выполняются от 0 (включительно) до его длины (исключительной), поэтому сама длина никогда не является допустимым индексом).

Ваш тест должен состоять if i != len(l) - 1: в том, чтобы исключить случай, когда i 1 индекс не является законным. Или проще (и гораздо эффективнее), просто ограничьте range в первую очередь, чтобы вам не нужно было добавлять 1 и напрямую пропускать индекс 0 , как это делает ваш текущий код:

 for m in range(x):
    for i in range(1, len(l)):
        l[i].append(m)
  

Имейте в виду, что в этих конкретных обстоятельствах вы могли бы просто построить финал l с:

 l = [[]]   [list(range(20)) for _ in range(1, x)]
  

или без, возможно, чрезмерно плотного listcomp:

 l = [[]]
for _ in range(1, x):
    l.append(list(range(20)))
  

поскольку это то, что ваш код делает несколько окольным путем.

Ответ №2:

Я рассмотрю причину, по которой это:

 if i != len(l):
  

не работает.

Я пропущу цикл вперед, пока мы не доберемся до m=0 и i=19 .

 for m in range(x): # m=0 (still on the first loop)
    for i in range(len(l)): # i=19 (the highest index it will reach)
        ...
  

Строка

 if i != len(l):
  

Говорит: «Пока текущее значение для i не равно 20 (начальная длина списка), следующий код безопасен для запуска».

Но что происходит, когда i=19 ?

Оператор if проверит i , не равно ли (19) 20, и, поскольку эта проверка прошла успешно, будет запущена следующая строка кода:

 l[i 1].append(m)
  

С i=19 помощью этого будет выполнено следующее:

 l[i 1].append(m)
# then
l[19 1].append(m)
# then
l[20].append(m)
# then
IndexError: list index out of range
  

Поскольку 20 находится за пределами диапазона списка. Индексы списка идут только от 0 до 19 !

Вот почему ваша проверка не работает.