Заполнение списка / массива по индексу в Python? - PullRequest
26 голосов
/ 15 мая 2009

Возможно ли это:

myList = []

myList[12] = 'a'
myList[22] = 'b'
myList[32] = 'c'
myList[42] = 'd'

Когда я пытаюсь, я получаю:

# IndexError: list assignment index out of range # 

Ответы [ 7 ]

50 голосов
/ 15 мая 2009

Вам нужно будет предварительно заполнить его чем-нибудь (например, 0 или None), прежде чем индексировать его:

myList = [None] * 100  # Create list of 100 'None's
myList[12] = 'a'  # etc.

В качестве альтернативы, используйте dict вместо списка, как Алекс Мартелли предложил .

27 голосов
/ 15 мая 2009

Для «разреженного списка» вы можете использовать dict вместо:

mylist = {}
mylist[12] = 'a'

и т.д.. Если вы хотите фактический список (инициализируйте его с [], , а не (), конечно! -), вам необходимо заполнить неустановленные слоты до _some_thing, например None, с помощью небольшой вспомогательной функции или путем подкласса list.

18 голосов
/ 15 мая 2009

Вот краткая оболочка списка, которая автоматически расширит ваш список нулями, если вы попытаетесь присвоить значение индексу после его длины.

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]
2 голосов
/ 15 мая 2009

Если вы не знаете размер списка заранее, вы можете использовать try / exception, а затем расширить список за исключением:

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
2 голосов
/ 15 мая 2009

Не без заполнения других мест в списке чем-либо (например, None или пустой строкой). Попытка вставить элемент в список с помощью написанного вами кода приведет к IndexError.

Там также mylist.insert, но этот код:

myList.insert(12,'a')

просто вставит 'a' в первое незанятое место в списке (в вашем примере это будет 0).

Итак, как я уже сказал, в списке должно быть что-то в индексах 0-11, прежде чем вы сможете вставить что-то в myList[12].

1 голос
/ 17 ноября 2013

На всякий случай, если кому-то нужно, я нашел решение для моей проблемы, мне нужно вычислить много факториалов , некоторые из них можно повторить , так что вот мой решение:

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,557 с

Используя приведенный выше код (список для хранения повторяющихся значений): 1.011 s

0 голосов
/ 04 марта 2019

Здание поверх Триптиха. Если вы хотите список произвольных размеров

class dynamiclist(list):
    """ List not needing pre-initialization

    Example:
        l = dynamiclist()
        l[20][1] = 10
        l[21][1] = 20
    """

    def __setitem__(self, index, value):
        size = len(self)
        if index >= size:
            self.extend(dynamiclist() for _ in range(size, index + 1))

        list.__setitem__(self, index, value)

    def __getitem__(self, index):
        size = len(self)
        if index >= size:
            self.extend(dynamiclist() for _ in range(size, index + 1))  # allows dimensions > 1

        return list.__getitem__(self, index)

Пример

l = dynamiclist()
l[20][1] = 10
l[21][1] = 20
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...