【问题标题】:Most efficient way to check if a group is a subgroup of other group using any data structure on Python 3使用 Python 3 上的任何数据结构检查组是否是其他组的子组的最有效方法
【发布时间】:2018-11-01 21:22:13
【问题描述】:

如果我可以在对象列表、整数列表和字典之间进行选择(还有其他数据结构选项吗?),这是发现一个组是否是其他组的子组的最有效的数据结构,以及如何实施?

我有一个具有唯一整数属性的类,因此我可以通过它们包含的整数或对象(指针)本身来“表示”类对象。

a.atributeEx = 1
b.atributeEx = 2
c.atributeEx = 3

listOfPointers = [a,b,c]
listAtributes = [1,2,3]
dictEx = ['1':1, '2':2, '3':3]

一种选择是使用 issubset,如下所示:

listAtributes2 = [1,2]
set(listAtributes).issubset(listAtributes2)

但是,使用带有属性列表的 issubset 函数,我的代码需要数月到数年才能完成运行,因为这必须执行数十亿次。通常,一个列表有 1 到 4 个元素,而另一个列表有 200 到 2000 个元素。

解决这个问题的最佳方法是什么?

【问题讨论】:

  • 你想用它做什么?使用set.issubset 应该是相当有效的,也许你选择了错误的语言……或者错误的抽象。
  • 您能否将数据预先转换为集合类型,以防止每次比较时都需要迭代和创建集合对象?您在这里谈论多少原始数据?
  • set(listAttributes) <= set(listAttributes2) 应该相当高效和快速,肯定比原生 Python 提供的任何其他东西都快。在什么情况下需要几个月到几年的时间?
  • 在两个或多个比较中,两个集合中的任何一个是否相同?那么,它们多久相同一次?例如。是否只有 50 亿个不同的集合包含 20-200 个元素和 10 亿个包含 1-4 个元素,或者在决定数据结构和算法时可能相关的任何其他比率。
  • @gahooa 我更改了代码以将数据预转换为设置类型,现在我的结果要好得多。但是,我注意到将 set.issubset 与数字、字符串和对象集(数字集是最快的)一起使用之间存在一些效率差异。有没有办法使用 set.issubset 来比较指针?这样:a = 1b = aset(a).issubset(b) 将返回 True,而 a = 1b = 1set(a).issubset(b) 将返回 False?

标签: python python-3.x list dictionary hashtable


【解决方案1】:

使用set 方法应该是相当有效的。特别是,如果您使用x.issubset(y),则只有x 的大小很重要,因为set 使用散列来检查它是否包含给定的项目。

虽然,如果您为每次比较都实例化一个集合,那么您的计算就会增加很大的开销。

一种解决方案是仅在您的__init__ 方法中实例化一个新的set,并在您的__setattr__ 方法中填充它。为了也允许删除属性,您可以定义一个__delattr__ 方法,从set 中删除元素。最后,在使用关键字in时,可以使用__contains__方法进行子集比较。

class Container:
    def __init__(self, **kwargs):
        self.__dict__['_attr_set'] = set()
        for k, v in kwargs.items():
            setattr(self, k, v)

    def __setattr__(self, key, value):
        self._attr_set.add((key, value))
        super().__setattr__(key, value)

    def __delattr__(self, item):
        for x in self._attr_set:
            if x[0] == item:
                self._attr_set.remove(x)
                break
        super().__delattr__(item)


    def __contains__(self, item):
        return item._attr_set.issubset(self._attr_set)

示例

x = Container(a=1, b=2, c=3)
y = Container(a=1, b=2)

print(y in x) # True

【讨论】:

    【解决方案2】:

    查看 python 集合。 set 数据类型具有您需要的所有操作(例如 issubset),而且速度非常快。如果您可以简化调用代码并让集合完成工作,您会看到它的表现很好。

    >>> x = set(range(1000))
    >>> y = {8,37,29,983}
    >>> y.issubset(x) 
    True
    

    所以我把它放在一个循环中。它在 27 秒内运行了 100,000,000 次。

    我认为,如果您预先计算您的集合,而不是为每次比较构建它们,您会发现这是一种超级有效的处理方式。

    https://docs.python.org/3/tutorial/datastructures.html#sets

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 2021-05-03
      • 2011-10-28
      • 2017-12-09
      • 2014-02-07
      相关资源
      最近更新 更多