gpt4 book ai didi

python - 在 Python 2.7 中包装大列表以使其不可变

转载 作者:行者123 更新时间:2023-11-28 22:51:58 24 4
gpt4 key购买 nike

如果我有一个非常大的 list(>100k 元素)可以通过函数调用从某个对象中检索,有没有办法包装该列表以使其对调用者不可变将其复制到 tuple

在下面的示例中,我只有一个 list 字段,但该解决方案应该适用于任意数量的 list 字段。

class NumieHolder(object):

def __init__(self):
self._numies = []

def add(self, new_numie):
self._numies.append(new_numie)

@property
def numies(self):
# return numies embedded in immutable wrapper/view
return ??? numies ???

if __name__ == '__main__':
nh = NumieHolder()

for numie in xrange(100001): # >100k holds
nh.add(numie)

# messing with numies should result in exception
nh.numies[3] = 4

# but I still want to use index operator
print '100th numie:', nh.numies[99]

我会知道如何编写以这种方式运行的适配器,但如果已经有一些我不知道的标准解决方案(即在标准库或广为人知的库中),我很感兴趣。

最佳答案

不幸的是,标准库(或其他著名的库)中没有这样的包装器。主要原因是 list 应该是具有索引访问权限的可变序列类型。 不可变 序列类型将是一个元组,正如您自己所说的那样。所以通常,使列表不可变的标准方法是通过调用 tuple(lst) 将其变成元组。

这显然不是您想要的,因为您希望避免复制所有元素。因此,您可以创建一个包装列表的自定义类型,并提供所有非修改方法 list 还支持:

class ImmutableList:
def __init__ (self, actualList):
self.__lst = actualList
def __len__ (self):
return self.__lst.__len__()
def __getitem__ (self, key):
return self.__lst.__getitem__(key)
def __iter__ (self):
return self.__lst.__iter__()
def __reversed__ (self):
return self.__lst.__reversed__()
def __contains__ (self, item):
return self.__lst.__contains__(item)
def __repr__ (self):
return self.__lst.__repr__()
def __str__ (self):
return self.__lst.__str__()
>>> original = [1, 2, 3, 4]
>>> immutable = ImmutableList(original)
>>> immutable
[1, 2, 3, 4]
>>> immutable[2]
3
>>> for i in immutable:
print(i, end='; ')

1; 2; 3; 4;
>>> list(reversed(immutable))
[4, 3, 2, 1]
>>> immutable[1] = 4
Traceback (most recent call last):
File "<pyshell#39>", line 1, in <module>
immutable[1] = 4
TypeError: 'ImmutableList' object does not support item assignment

另一种方法是子类型 list 并覆盖 __setitem____delitem__ 来引发异常,但我建议不要这样做,因为list 的子类型应该具有与 list 本身相同的接口(interface)。另一方面,上面的 ImmutableList 只是一些可索引的序列类型,它恰好包装了一个真正的列表本身。除此之外,将它作为 list 的子类型实际上需要你复制一次内容,所以如果你不想重新创建所有这些项目(这似乎是你的点——否则你可以只使用 tuple)。

关于python - 在 Python 2.7 中包装大列表以使其不可变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21000994/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com