Python,扩展列表对象以包含每个元素的权重
Python, extend a list object to include weights for each element
我正在尝试扩展一个 list
对象,使其也与每个元素相关联,即自定义权重。我想将默认权重与添加到列表中的每个元素相关联,并提供稍后修改此权重的选项。检索元素时,还应返回其权重。
我应该如何通过扩展列表 class 来实现这一点?我在 python 中阅读了一些关于 data modeling 的内容,但我不确定如何使用 __getitem__
和 __setitem__
仿真。
How should I achieve this via extending the list class?
不要那样做。这将破坏数据结构。列表是异构数据类型的通用结构。为每个元素强制使用 pair 类型将不可避免地违反列表的含义。扩展 class 或继承意味着您通过添加更多功能而不是限制它来实现专业化。
你实际上应该做的是创建一个模型,其中的一个成员是
- 元组对联
- 命名元组
- 具有两个元素的简单结构
而不是考虑扩展列表是您所能做的最糟糕的事情。
我正在用 collections.abc 波纹管写出更完整的答案,而我刚刚想到,您很可能会接受 OrderedDict:
保留顺序的 key:value 对映射(其中 "weight" 是您的值)。
只需执行 from collections import OrderedDict
并使用它代替您的自定义列表 - 将任何 "append(element)" 替换为 "mydict[element] = weight"
https://docs.python.org/2/library/collections.html
如果您确实需要自定义的类似列表的对象,请继续阅读:
我最初的想法 - 一种使用自定义真正创建类列表对象的方法behavior/elements。
从技术上讲,您可以继承 list
- 但由于
关于 Python 如何实现的相互关系的技术问题
一个列表内置方法,你最好实现一个
collections.abc.MutableSequence
子类比列表的子类。
(注意 Python 2.x 只是 collections.MutableSequence
- Python 3 添加了 "abc" 命名空间。)
如果您查看此处的文档 - https://docs.python.org/dev/library/collections.abc.html,您会发现您可以使用类似对象的列表,您只需实现:
__getitem__, __setitem__, __delitem__, __len__, insert
方法,Python 会为您处理剩下的事情。
而他们,您可以有一个内部 Python 列表来保存您的数据,以聚合模式 - 并让它处理您对类似列表的迭代的所有访问。在此列表中,只需为您想要的每个数据元素保留双元组或双元素列表 - 第一个元素是您的元素,第二个元素是您想要的权重。然后,只需添加几个额外的方法即可让您显式 get/reset 您的权重参数。
# Python 2/3 compatibility snippet:
try:
from collections import MutableSequence
except ImportError:
from collections.abc import MutableSequence
class WList(MutableSequence):
def __init__(self, *args, **kw):
self.data = list(*args, **kw)
def __getitem__(self, index):
return self.data[index]
def __setitem__(self, index, value):
if len(value) != 2:
raise TypeError ("You have to pass a value and a weight")
self.data[index] = value
def __delitem__(self, index):
del self.data[index]
def __len__(self):
return len(self.data)
def insert(self, index, value):
if len(value) !=2:
raise TypeError ("You have to pass a value and a weight")
self.data.insert(index, value)
def set_weight(self, index, weight):
self.data[index] = (self.data[index][0], weight)
def __repr__(self):
return "Wlist(%r)" % self.data
但是......实际上,考虑到你的问题,这看起来有点过分了——你可能可以直接使用 OrderedDict。
我正在尝试扩展一个 list
对象,使其也与每个元素相关联,即自定义权重。我想将默认权重与添加到列表中的每个元素相关联,并提供稍后修改此权重的选项。检索元素时,还应返回其权重。
我应该如何通过扩展列表 class 来实现这一点?我在 python 中阅读了一些关于 data modeling 的内容,但我不确定如何使用 __getitem__
和 __setitem__
仿真。
How should I achieve this via extending the list class?
不要那样做。这将破坏数据结构。列表是异构数据类型的通用结构。为每个元素强制使用 pair 类型将不可避免地违反列表的含义。扩展 class 或继承意味着您通过添加更多功能而不是限制它来实现专业化。
你实际上应该做的是创建一个模型,其中的一个成员是
- 元组对联
- 命名元组
- 具有两个元素的简单结构
而不是考虑扩展列表是您所能做的最糟糕的事情。
我正在用 collections.abc 波纹管写出更完整的答案,而我刚刚想到,您很可能会接受 OrderedDict: 保留顺序的 key:value 对映射(其中 "weight" 是您的值)。
只需执行 from collections import OrderedDict
并使用它代替您的自定义列表 - 将任何 "append(element)" 替换为 "mydict[element] = weight"
https://docs.python.org/2/library/collections.html
如果您确实需要自定义的类似列表的对象,请继续阅读:
我最初的想法 - 一种使用自定义真正创建类列表对象的方法behavior/elements。
从技术上讲,您可以继承 list
- 但由于
关于 Python 如何实现的相互关系的技术问题
一个列表内置方法,你最好实现一个
collections.abc.MutableSequence
子类比列表的子类。
(注意 Python 2.x 只是 collections.MutableSequence
- Python 3 添加了 "abc" 命名空间。)
如果您查看此处的文档 - https://docs.python.org/dev/library/collections.abc.html,您会发现您可以使用类似对象的列表,您只需实现:
__getitem__, __setitem__, __delitem__, __len__, insert
方法,Python 会为您处理剩下的事情。
而他们,您可以有一个内部 Python 列表来保存您的数据,以聚合模式 - 并让它处理您对类似列表的迭代的所有访问。在此列表中,只需为您想要的每个数据元素保留双元组或双元素列表 - 第一个元素是您的元素,第二个元素是您想要的权重。然后,只需添加几个额外的方法即可让您显式 get/reset 您的权重参数。
# Python 2/3 compatibility snippet:
try:
from collections import MutableSequence
except ImportError:
from collections.abc import MutableSequence
class WList(MutableSequence):
def __init__(self, *args, **kw):
self.data = list(*args, **kw)
def __getitem__(self, index):
return self.data[index]
def __setitem__(self, index, value):
if len(value) != 2:
raise TypeError ("You have to pass a value and a weight")
self.data[index] = value
def __delitem__(self, index):
del self.data[index]
def __len__(self):
return len(self.data)
def insert(self, index, value):
if len(value) !=2:
raise TypeError ("You have to pass a value and a weight")
self.data.insert(index, value)
def set_weight(self, index, weight):
self.data[index] = (self.data[index][0], weight)
def __repr__(self):
return "Wlist(%r)" % self.data
但是......实际上,考虑到你的问题,这看起来有点过分了——你可能可以直接使用 OrderedDict。