Python,扩展列表对象以包含每个元素的权重

时间:2015-04-20 16:40:37

标签: python oop data-modeling

我正在尝试扩展list对象以与每个元素(自定义权重)相关联。我想将默认权重与添加到列表中的每个元素相关联,并选择稍后修改此权重。检索元素时,还应返回其权重。 我应该如何通过扩展列表类来实现这一目标?我在python中阅读了一些关于data modeling但我不确定如何使用__getitem____setitem__仿真。

2 个答案:

答案 0 :(得分:1)

  

如何通过扩展列表类来实现这一目标?

不要那样做。这将破坏数据结构。 List是异构数据类型的通用结构。为每个元素强制执行一对类型将不可避免地违反列表的内容。扩展类或继承意味着您通过添加更多功能而不是通过限制来专门化。

您实际应该做的是创建一个带有

列表成员的模型
  • tuple couplet
  • namedtuple
  • 具有两个元素的简单结构

而是考虑扩展列表是你可能做的最糟糕的事情。

答案 1 :(得分:1)

我正在写一个更完整的回答,上面有collections.abc,它刚刚发生,你很可能会对OrderedDict很好: 密钥:值对的映射(其中“权重”是您的值)预先确定顺序。

只需执行from collections import OrderedDict并使用它代替自定义列表 - 将“append(element)”替换为“mydict [element] = weight”

https://docs.python.org/2/library/collections.html

如果您确实需要类似自定义列表的对象,请继续阅读:

我最初的想法 - 一种真正使用自定义行为/元素创建类似列表的对象的方法。

你可以从技术上继承list - 但是由于 有关Python如何实现相互关系的技术问题 列表内置方法,你最好实现一个 collections.abc.MutableSequence子类,而不是列表的子类。

(NB Python 2.x它只是collections.MutableSequence - Python 3添加了“abc”命名空间。)

如果你查看这里的文档 - https://docs.python.org/dev/library/collections.abc.html,你会看到你可以获得一个像你只需要实现的对象的列表: __getitem__, __setitem__, __delitem__, __len__, insert方法,Python将为您完成其余的工作。

他们,您可以拥有一个内部Python列表来保存您的数据,采用聚合模式 - 并让它处理所有访问类似列表的迭代。在此列表中,只需为您想要的每个数据元素保留两元组或两元素列表 - 第一个元素是您的元素,第二个元素是您想要的权重。然后,只需添加一些额外的方法,以允许您显式获取/重置您的权重参数。

# 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。