• Python问题:计数器比较作为 Bag-type


    问题描述:

    我需要 Python 中的类似包/多集的数据类型。我了解 collections.Counter 经常用于此目的。但是比较运算符似乎不起作用:

    1. In [1]: from collections import Counter
    2. In [2]: bag1 = Counter(a=1, b=2, c=3)
    3. In [3]: bag2 = Counter(a=2, b=2)
    4. In [4]: bag1 > bag2
    5. Out[4]: True

    这对我来说似乎是一个错误。我希望小于和大于运算符执行类似集合的子集和超集比较。但如果是这种情况,那么bag1 > bag2将是错误的,因为bag2包含一个额外的'a'. Counter 对象上似乎也没有子集/超集方法。所以我有两个问题:

    1. Counter 对象使用什么比较逻辑?

    2. 如何比较 Counter 对象的子集、超集、真子集和真超集?

    解决思路一:

    我们可以像这样实现“多集包含”检查,而不是使用all迭代Counter值:

    1. from collections import Counter
    2. from functools import total_ordering
    3. class PartiallyOrderedCounter(Counter):
    4. def __le__(self, other):
    5. """ Multiset inclusion """
    6. test = self.copy()
    7. test.subtract(other)
    8. return not -test
    9. def __lt__(self, other):
    10. """ Multiset strict inclusion """
    11. return self <= other and self != other

    这可能效率较低,但足够有趣,值得一提。

    它是如何工作的:Counter一元否定(以及二元-运算符)的实现否定了结果中的每个计数器值,但随后也去除了所有负数或零。同时,该.subtract方法在原地运行(需要复制),但允许结果为负数。因此,当我们对减法的结果求反时,我们Counter只得到一个“缺失”的值other(创建被否定为正数的负数)。当且仅当没有这样的值时,计数器对象是 Falsey,我们True通过应用not逻辑运算符返回。

    解决思路二:

    这个悬而未决的问题很有趣:

    • 如何比较 Counter 对象的子集、超集、真子集和真超集?

    通过定义缺少的“丰富的比较方法”。您也可以使用自由函数,这将使客户端代码更加明确。

    1. from collections import Counter
    2. class PartiallyOrderedCounter(Counter):
    3. def __le__(self, other):
    4. """ Multiset inclusion """
    5. return all( v <= other[k] for k,v in self.items() )
    6. def __lt__(self, other):
    7. """ Multiset strict inclusion """
    8. return self <= other and self != other
    9. # TODO : __ge__ and __gt__
    10. # Beware : they CANNOT be written in terms of __le__ or __lt__
    11. a = PartiallyOrderedCounter('abc')
    12. b = PartiallyOrderedCounter('ab')
    13. c = PartiallyOrderedCounter('abe')
    14. assert a <= a
    15. assert not a < a
    16. assert b <= a
    17. assert b < a
    18. assert not a < b
    19. assert not c <= a
    20. assert not a <= c

    解决思路三:

    以上仅为部分解决思路,添加下方公众号后回复001,即可查看全部内容。公众号有许多评分最高的编程书籍和其它实用工具,无套路,可放心使用

    如果您觉得有帮助,可以关注公众号——立志于成为对程序员有益的公众号

  • 相关阅读:
    NVIDIA 7th SkyHackathon(六)Tao 目标检测模型训练与评估
    读Shape-Guided代码②
    Salesforce使用的数据库是什么
    Rust 利用 Trait 实现多态性
    实践 - 搭建Redis一主两从三哨兵
    devtools安装
    环形缓冲区-----适合在通信中接收数据(例如uart)
    【系统概念】容错、高可用和灾备
    自动化运维平台-OpManager
    【老生谈算法】matlab实现Kmeans聚类算法源码——Kmeans聚类算法
  • 原文地址:https://blog.csdn.net/qq_38334677/article/details/126146110