Разреженный список назначений в python

Мне нужен список со следующим поведением

>>> l = SparseList()
>>> l
[]
>>> l[2] = "hello"
>>> l
[ None, None, "hello"]
>>> l[5]
None
>>> l[4] = 22
>>> l
[ None, None, "hello", None, 22]
>>> len(l)
5
>>> for i in l: print i
None
None
"hello"
None
22

Хотя он может "эмулироваться" через словарь, он не совсем то же самое. массив numpy может вести себя таким образом, но я не хочу импортировать весь numpy для чего-то подобного. Перед его кодированием я спрашиваю, существует ли что-то подобное в стандартной библиотеке.

Ответ 1

Здесь минимальный код для передачи ваших приведенных примеров (с необходимыми настройками: вы ожидаете странного интервала и цитирования, "Нет" для распечатки в приглашении без инструкции print и т.д. и т.д.):

class SparseList(list):
  def __setitem__(self, index, value):
    missing = index - len(self) + 1
    if missing > 0:
      self.extend([None] * missing)
    list.__setitem__(self, index, value)
  def __getitem__(self, index):
    try: return list.__getitem__(self, index)
    except IndexError: return None

__test__ = dict(allem='''
>>> l = SparseList()
>>> l
[]
>>> l[2] = "hello"
>>> l
[None, None, 'hello']
>>> print l[5]
None
>>> l[4] = 22
>>> l
[None, None, 'hello', None, 22]
>>> len(l)
5
>>> for i in l: print i
None
None
hello
None
22
''')
import doctest
doctest.testmod(verbose=1)

Я предполагаю, что вам нужно больше (для поддержки отрицательных индексов, нарезки и всего остального), но это все ваши примеры неявно указывают.

Ответ 2

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

sparse_vars = [(0,"Hi"),(10000,"Bye"),(20000,"Try")]
sparse_list = {}

for var in sparse_vars:
  sparse_list[var[0]] = var[1]

>>> print sparse_list
{0: 'Hi', 10000: 'Bye', 20000: 'Try'}
>>> print sparse_list[20000]
'Try'