Возможно ли это:
myList = []
myList[12] = 'a'
myList[22] = 'b'
myList[32] = 'c'
myList[42] = 'd'
Когда я пытаюсь, я получаю:
# IndexError: list assignment index out of range #
Возможно ли это:
myList = []
myList[12] = 'a'
myList[22] = 'b'
myList[32] = 'c'
myList[42] = 'd'
Когда я пытаюсь, я получаю:
# IndexError: list assignment index out of range #
Вам нужно предварительно заполнить его чем-нибудь (например, 0
или None
), прежде чем вы сможете его проиндексировать:
myList = [None] * 100 # Create list of 100 'None's
myList[12] = 'a' # etc.
В качестве альтернативы используйте опцию вместо списка, поскольку предложил Алекс Мартелли.
Для "разреженного списка" вместо dict
можно использовать
mylist = {}
mylist[12] = 'a'
и т.д.. Если вам нужен фактический список (инициализируйте его с помощью []
, а не ()
, конечно! -), вам нужно заполнить не установленные слоты для _some_thing, например. None
, с помощью небольшой вспомогательной функции или путем подкласса list
.
Вот краткий список, который автоматически расширит ваш список нулями, если вы попытаетесь присвоить значение индексу за его длину.
class defaultlist(list):
def __setitem__(self, index, value):
size = len(self)
if index >= size:
self.extend(0 for _ in range(size, index + 1))
list.__setitem__(self, index, value)
Теперь вы можете сделать это:
>>> a = defaultlist([1,2,3])
>>> a[1] = 5
[1,5,3]
>>> a[5] = 10
[1,5,3,0,0,10]
Не заселяйте другие места в списке чем-то (например, None
или пустая строка). Попытка вставить элемент в список с использованием кода, который вы написали, приведет к IndexError
.
Там также mylist.insert
, но этот код:
myList.insert(12,'a')
просто вставляет 'a' в первое незанятое место в списке (это будет 0, используя ваш пример).
Итак, как я уже сказал, в списке должно быть что-то в индексе 0-11, прежде чем вы сможете вставить что-то в myList[12]
.
Если вы не знаете размер списка раньше времени, вы можете использовать try/except, а затем Extend list в файле except:
L = []
def add(i, s):
try:
L[i] = s
except IndexError:
L.extend([None]*(i-len(L)+1))
L[i] = s
add(12, 'a')
add(22, 'b')
----- Обновить -------------------------------------- -------
За комментарий tgray: если вероятность того, что ваш код будет генерировать исключение большую часть времени, вы должны проверять длину списка каждый раз и избегать Исключения:
L = []
def add(i, s):
size = len(L)
if i >= size:
L.extend([None]*(i-size+1))
L[i] = s
На всякий случай, кому-то нужно, я решил решить проблему, мне нужно было вычислить много факториалов, некоторые из них могли быть повторены, поэтому здесь это мое решение:
factorials = {}
def calcFact(v):
try:
return factorials[v]
except KeyError:
factorials[v] = math.factorial(v)
return factorials[v]
TestCase:
calcFact(99000)
calcFact(90900)
calcFact(90090)
calcFact(90009)
calcFact(90009) #repeated
calcFact(90009) #repeated
Результаты:
Повторение математических вычислений: 1.576 s
Используя приведенный выше код (список для хранения повторяющихся значений): 1.011 s