【问题标题】:Python, extend a list object to include weights for each element [closed]Python,扩展一个列表对象以包含每个元素的权重[关闭]
【发布时间】:2015-04-21 04:11:44
【问题描述】:

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

【问题讨论】:

    标签: python oop data-modeling


    【解决方案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 子类比列表的子类。

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

    如果您在此处查看文档 - https://docs.python.org/dev/library/collections.abc.html,您会发现您可以摆脱类似对象的列表,您只需要实现: __getitem__, __setitem__, __delitem__, __len__, insert 方法,Python 会为你处理剩下的事情。

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

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

    【讨论】:

      【解决方案2】:

      我应该如何通过扩展列表类来实现这一点?

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

      您实际上应该做的是创建一个具有列表成员的模型,其中一个

      • 元组对联
      • 命名元组
      • 具有两个元素的简单结构

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

      【讨论】:

      • 你从哪里得到这个子类永远不应该限制父类做什么的定义?对于该陈述的荒谬的一个例子:“抽象”类的概念如何工作 - 因为通常具体实现就是这样做的(定义数据类型)?对特定数据类型的列表限制不亚于列表 - 因为列表可以与该数据子集一起存在。
      • 此外:如果面向对象无论如何都会根据增加/限制父类来限制子类应该做什么,那么增加它们应该是被禁止的事情会更有意义,而不是相反大约。幸运的是,它也不限制。
      猜你喜欢
      • 2020-10-19
      • 1970-01-01
      • 2021-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多