Python 列表在索引不存在时设置值

19 投票
4 回答
38981 浏览
提问于 2025-04-17 22:11

有没有什么方法、库或者其他东西可以让我们在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 个回答

1

你不能创建一个有空缺的列表。你可以使用一个 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']
3

如果你真的想知道这个问题的语法,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] 会返回一个 KeyError 错误,但在 defaultdict 中,它会直接创建一个空的 defaultdict,然后把它加进去,再返回这个空的字典。

其他可能的实现方式,比如支持不同的语法糖,可能需要自定义类等等,这样会有其他的权衡。

4

这不是绝对可靠的方法,但看起来最简单的办法就是先创建一个比你实际需要的要大的列表,也就是说:

l = [None for i in some_large_number]
l[3] = 'foo'
# [None, None, None, 'foo', None, None None ... ]
17

虽然没有现成的功能,但其实实现起来很简单:

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

撰写回答