【问题标题】:Is there a Python equivalent for C++ "multiset<int>"?是否有 C++“multiset<int>”的 Python 等价物?
【发布时间】:2013-06-25 04:13:43
【问题描述】:

我正在将一些 C++ 代码移植到 Python,其中一个数据结构是一个多重集,但我不确定如何在 Python 中对此进行建模。

ms 成为 C++ multiset&lt;int&gt;

如何使用ms(发布一些示例)

multiset<int>::iterator it = ms.find(x)
ms.erase(it)

ms.insert(x)
ms.end()
ms.lower_bound(x)
ms.clear()

【问题讨论】:

  • 你可以在python中查看Counter类:docs.python.org/2/library/collections.html#collections.Counter
  • 我列出的功能/方法是否有等价物?
  • 那么多重集只是一个带有内置对数查找的有序列表吗?即我可以使用 bisect 模块或二进制搜索功能的 Python 列表?
  • 我用谷歌搜索并没有找到我想要的东西。如果您只想回复“snark”,请不要在此帖子中回复。
  • C++ multiset 似乎比 Python Counter 有更丰富的接口。此外,C++ multiset 是有序的,所以像 lower_bound 这样的方法在 Python 的 Counter 中没有任何意义。基本上,它们的用例有些重叠,但它们不是一回事。

标签: c++ python set multiset


【解决方案1】:

没有。有关 Python 中 C++ 树容器(mapsetmultimapmultiset)等价物的一般性讨论,请参阅 Python's standard library - is there a module for balanced binary tree?

我能想到的最接近的方法是使用字典将整数映射到计数(也是整数)。但是,这不会让您按顺序获得密钥,因此您无法使用lower_bound 进行搜索。另一种方法是使用有序列表,正如其他人已经建议的那样,也许是(整数,计数)元组的列表?如果您只需要在完成所有插入后进行搜索,您可以使用字典作为临时结构进行构建,在完成所有插入后构建列表,然后使用列表进行搜索。

【讨论】:

  • 是的,代码先做了很多插入,然后搜索/删除各种项目。两个进程都使用了很多 lower_bound 调用。
  • @MrP 你知道为什么在插入过程中有lower_bound调用吗? Re lower_bound 在删除过程中调用,如果您有一个 (integer, count) 元组列表,您可以通过减少计数来删除项目,如果计数达到零,您可以将项目留在那里并稍后清理。 (插入全新的整数会更成问题!)
【解决方案2】:

有几种符合您标准的排序列表数据类型的实现。两个流行的选择是SortedContainersblist 模块。这些模块中的每一个都提供了一个SortedList 数据类型,该数据类型自动按排序顺序维护元素,并允许快速插入和下限/上限查找。还有一个performance comparison 也很有帮助。

使用 SortedContainers 模块中的 SortedList 类型的等效代码是:

from sortedcontainers import SortedList
sl = SortedList()

# Start index of `x` values
start = sl.bisect_left(x)

# End index of `x` values
end = sl.bisect_right(x)

# Iterator for those values
iter(sl[start:end])

# Erase an element
del sl[start:end]

# Insert an element
sl.add(x)

# Iterate from lower bound
start = sl.bisect_left(x)
iter(sl[x] for x in range(start, len(sl)))

# Clear elements
sl.clear()

所有这些操作都应该在排序列表数据类型上有效地工作。

【讨论】:

    【解决方案3】:

    有几个数据结构很接近。

    • python 集合:

      • 有序字典:添加了记住订单条目的字典子类。 link
      • Counter:用于计算可散列对象的 dict 子类。 link
    • 由django框架提供:

      • 具有多个具有相同值的键的字典:link
      • 作为python集合弃用的排序字典现在包括一个有序字典:link

    【讨论】:

      【解决方案4】:

      您可以使用bisect 函数使列表保持有序。比如find会变成

      def index(a, x):
          'Locate the leftmost value exactly equal to x'
          i = bisect_left(a, x)
          if i != len(a) and a[i] == x:
              return i
          raise ValueError
      

      您会发现其他等价物in the docs。你现在将得到一个ValueError,而不是检查end

      【讨论】:

        【解决方案5】:

        如果您不需要排序,可以将其用作multiset&lt;int&gt;(或unordered_multiset&lt;int&gt;):

        from collections import Counter
        
        def multiset(array):
            return set(Counter(array).items())
        

        【讨论】:

          猜你喜欢
          • 2021-03-29
          • 2012-07-17
          • 2012-06-14
          • 2012-12-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-14
          相关资源
          最近更新 更多