Индекс и списки — Индекс вне диапазона

#python #list

#python #Список

Вопрос:

Разве следующий код не должен выводиться? 100 100

 price = 100  # assigns 'price' reference to 100
price = [price] # creates a 'price' list with 1 element: [100]

for i in range(1, 3):
    print(price[0]) # prints 100
    price[i] = price[i - 1]
    price.append(price[i])
    print(price[i])
  

Получение IndexError: list assignment index out of range ошибки в строке price[i] = price[i - 1] , но строка непосредственно перед печатью 100 выполнена успешно. Не следует ли price [i] просто получать присвоенное значение price[0]?

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

1. Проблема заключается в том, что при попытке получить доступ к python [i], индекс выбрасывается из диапазона. Оператор Left не является четным evaluated

2. Вы пытаетесь добавить элементы в список, смотрите ниже. Вы не можете просто присвоить значение несуществующим позициям индекса и ожидать, что список автоматически добавится или увеличится сам.

3. (Кстати, если вы априори знаете, что список будет содержать как минимум 3 элемента, вы могли бы инициализировать его price = [None] * 3 и вы получите [None, None, None] . Теперь вы можете напрямую назначать им. Но лучше явно выполнять append .)

Ответ №1:

Вы пытаетесь добавить элементы в список, или, точнее, инициализировать список повторяющимися копиями чего-либо. Вот Pythonic способы сделать это:

 # Use a list comprehension
>>> price = [100 for _ in range(3)]
[100, 100, 100]

# Use itertools.repeat
>>> import itertools
>>> list(itertools.repeat(100, 3))
[100, 100, 100]
  

Оба они выполняются быстрее, чем (многократное) выполнение append() , которое равно O (N), поэтому многократное выполнение append() равно O (N ^ 2) в длинном списке, который становится очень медленным.

(Кстати, если вы априори знаете, что список будет содержать как минимум N элементов, и N большое, вы могли бы инициализировать его price = [None] * N и вы получите [None, None, None...] . Теперь вы можете напрямую назначать им. Но явное выполнение append — лучшая практика для начинающих.)

Ответ №2:

Если вы просто пытаетесь добавить в список, попытка сделать это с индексом точно не сработает, потому что этот индекс отсутствует в списке:

 somelist = []
somelist[0] = 1
IndexError
  

Так что просто используйте append

 for i in range(1,3):
    price.append(price[i-1])
  

Ответ №3:

Проблема в том, что вы присваиваете индекс, слишком большой для длины массива.

для i в диапазоне (1, 3):

Это инициализирует i равным 1. Поскольку массивы индексируются с нулевым индексом, а длина вашего массива равна 1 при первом проходе, вы нажмете assignment out of range error на строку, которую вы упомянули (когда i=1 ).

Вот минимальный пример, показывающий проблему:

 my_array = ["foo"]
my_array[1] = "bar" # throws assignment out of range error
  

Ответ №4:

Вы не можете присвоить значение списку напрямую, почему в этом списке указан предыдущий определенный размер. Вы должны использовать append для добавления элементов в нужную позицию.

Проверьте:

 # Check the value on our initial position
print(price[0])
for i in range(1, 3):
    price.append(price[i-1])
    print(price[i])
  

Ответ №5:

Это не будет распечатано:

100

100

Вы инициализировали список с 1 элементом, размер этого списка равен 1. Однако ваш диапазон начинается с 1 для for цикла, что на самом деле происходит, так это:

 price = 100  # assigns 'price' to 100
price = [price] # creates a 'price' list with 1 element: [100]

for i in range(1, 3): # The list is 0-indexed, meaning price[0] contains 100
    print(price[0]) # prints 100 as it should
    price[i] = price[i - 1] # i is 1, price[i] is not an assigned value, i.e: you never assigned price[1]
    price.append(price[i]) # This doesn't execute because an exception was thrown
    print(price[i]) # Neither does this
  

Чтобы получить результат, который вы ищете, это сработало бы:

 price = [100] # creates a 'price' list with 1 element: [100]

for i in range(0, 2): # Start at index 0
    print(price[i]) # Print current index
    price.append(price[i]) # Append current value of price[i] to the price list
  

Чтобы убедиться, что все добавлено так, как вы ожидали, вы можете протестировать это с помощью len:

print(len(price))

Output:3

Тем не менее, это предпочтительный способ добавления, как показал @smci в своем ответе.