Python list устанавливает значение в индексе, если индекс не существует
есть ли способ, lib или что-то в python, что я могу установить значение в списке по индексу, который не существует? Что-то вроде создания индекса времени выполнения в списке:
l = []
l[3] = 'foo'
# [None, None, None, 'foo']
и более далее, с многомерными списками:
l = []
l[0][2] = 'bar'
# [[None, None, 'bar']]
или с существующего:
l = [['xx']]
l[0][1] = 'yy'
# [['xx', 'yy']]
4 ответов
нет встроенного, но его достаточно легко реализовать:
class FillList(list):
def __setitem__(self, index, value):
try:
super().__setitem__(index, value)
except IndexError:
for _ in range(index-len(self)+1):
self.append(None)
super().__setitem__(index, value)
или, если вам нужно изменить существующие списки ванили:
def set_list(l, i, v):
try:
l[i] = v
except IndexError:
for _ in range(i-len(l)+1):
l.append(None)
l[i] = v
вы не можете создать список с пробелами. Вы могли бы использовать dict
или этот быстрый маленький парень:
def set_list(i,v):
l = []
x = 0
while x < i:
l.append(None)
x += 1
l.append(v)
return l
print set_list(3, 'foo')
>>> [None, None, None, 'foo']
если вы действительно хотите синтаксис в вашем вопросе, defaultdict
вероятно, лучший способ получить его:
from collections import defaultdict
def rec_dd():
return defaultdict(rec_dd)
l = rec_dd()
l[3] = 'foo'
print l
{3: 'foo'}
l = rec_dd()
l[0][2] = 'xx'
l[1][0] = 'yy'
print l
<long output because of defaultdict, but essentially)
{0: {2: 'xx'}, 1: {0: 'yy'}}
это не совсем "список списков", но он работает более или менее как один.
вам действительно нужно указать вариант использования... выше имеет некоторые преимущества (вы можете получить доступ к индексам, не проверяя, существуют ли они в первую очередь), так и некоторые недостатки - например, l[2]
в нормальном dict вернет KeyError
, но в defaultdict
Он просто создает пустой defaultdict
, добавляет его, а затем возвращает его.
другие возможные реализации для поддержки различных синтаксических сахаров могут включать пользовательские классы и т. д., и будут иметь другие компромиссы.
не является надежным, но кажется, что самый простой способ сделать это-инициализировать список намного больше, чем вам нужно, т. е.
l = [None for i in some_large_number]
l[3] = 'foo'
# [None, None, None, 'foo', None, None None ... ]