Python列表 - "预留"空间(〜大小调整)

Grz*_*cki 18 python python-3.x

我有一份清单l,我想做任务:

l[index] = val
Run Code Online (Sandbox Code Playgroud)

但是可能存在列表太小的情况.

所以,我想确保我有新的价值空间.有时候,我需要与空字符串,以填补新的空间'',有时与其他物体(如空列表[],FalseNone).

对于此任务,我使用以下过程:

def ResizeList(l, size, fill_with=None):
    l += [fill_with]*(size-len(l))
Run Code Online (Sandbox Code Playgroud)

(注意:它即使有效size-len(l)<=0)(注意:由于我对保留空间感兴趣,我故意不要将截断为更短的列表)

像那样:

ResizeList(l, index+1)
l[index] = val
Run Code Online (Sandbox Code Playgroud)

(当与其他对象填充,这是这样的:ResizeList(l, index+1, []))

有更多的pythonic方法吗?这样做是否有一些内置函数或库函数?

我主要使用的是Python-3.x,但有关Python-2x的专业知识非常有用且受欢迎.

澄清:请不要告诉我dict,因为我需要list

对于那些希望我更具体的人:

问题陈述表明它与list类型有关.dict在这里使用不是一个选项或解决方案.这是有原因的,特别是与域有关(我正在做一个实验的原型,必须显示一些渐近行为,而不是 - 可能你已经习惯了 - 一个程序的原型.如果它将是"只是一个程序的原型",然后我同意使用dict和其他注释).我有以下假设:

  • 我有很多列表(需要关心内存和性能开销)
  • 由于工作流程和原型的需要,我无法调用手动编码的C/C++扩展
  • 在计算过程中,最终列表大小未知
  • 我们知道,在列表中会很密集
  • 列表单元格以未知顺序写入和覆盖

这些只是我强调我需要一个list而不是一个的几个原因dict.对于那些有兴趣了解更多详情或谁愿意要讨论dict,结账我们怎么样在这里讨论

NPE*_*NPE 7

如果您确定列表 - 而不是说dict- 是 - 是您用例的最佳数据结构,我建议使用以下类:

class rlist(list):
  def __init__(self, default):
    self._default = default
  def __setitem__(self, key, value):
    if key >= len(self):
      self += [self._default] * (key - len(self) + 1)
    super(rlist, self).__setitem__(key, value)

l = rlist(0)
print(l)
l[10] = 20
print(l)
l[5] = 14
print(l)
Run Code Online (Sandbox Code Playgroud)

此类检查分配的索引是否超出列表的当前长度,并根据需要自动扩展列表.

该代码兼容Python 2和3(使用2.6.5和3.1.2测试).

如果结构密集且您需要尽快通过索引找到元素,则此类可能很方便.如果结构稀疏,您应该考虑使用字典.

  • @BasicWolf为什么子类内置类型错了?它非常明确地允许新式类,例如http://python-history.blogspot.com/2010/06/new-style-classes.html (6认同)
  • @BasicWolf如果每个人都听取了这种智慧,我们可能永远不会得到`DefaultDict`. (6认同)
  • @BasicWolf所以`collections.OrderedDict`,`collections.Counter`,`collections.namedtuple`都是错误的,或者标准库是否具有子类内置类型的独特权利?(不像`defaultdict`,它是C编码的,我列出的都涉及内置的Python子类). (2认同)

Rik*_*ggi 6

我想出了一些使用itertool.repeat().

import itertools

def assign(lst, idx, value, fill=None):
    diff = len(lst) - idx
    if diff >= 0:
        lst[idx] = value
    else:
        lst.extend(itertools.repeat(fill, -diff))
        lst.append(value)
Run Code Online (Sandbox Code Playgroud)

具有以下行为:

>>> l = [0, 1, 2, 3, 4]
>>> assign(l, 2, 'new')
>>> l
[0, 1, 'new', 3, 4]
>>> assign(l, 8, 'new')
>>> l
[0, 1, 'new', 3, 4, None, None, None, 'new']
>>> assign(l, 10, 'new', fill=[])
>>> l
[0, 1, 'new', 3, 4, None, None, None, 'new', [], 'new']
Run Code Online (Sandbox Code Playgroud)

这对你有用吗?

编辑:自从问题更新后,我更新了答案。

  • @GrzegorzWierzowiecki:我们可以尝试在聊天中交谈http://chat.stackoverflow.com/rooms/6695/discussion- Between-rik-p-and-grzegorz-wierzowiecki (2认同)