是否有 C++“multiset<int>”的 Python 等价物?

Posted

技术标签:

【中文标题】是否有 C++“multiset<int>”的 Python 等价物?【英文标题】:Is there a Python equivalent for C++ "multiset<int>"? 【发布时间】: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 中没有任何意义。基本上,它们的用例有些重叠,但它们不是一回事。 【参考方案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】:

有几种符合您标准的排序列表数据类型的实现。两个流行的选择是SortedContainers 和blist 模块。这些模块中的每一个都提供了一个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())

【讨论】:

以上是关于是否有 C++“multiset<int>”的 Python 等价物?的主要内容,如果未能解决你的问题,请参考以下文章

是否有可能直接将 C++ 与 Metal API 一起使用

是否有 C++ DeckLink 输出的最小工作示例?

是否有适用于 C++ 的语义差异工具?

是否有返回字符的 ASCII 值的函数? (C++)

是否有哪个编译器支持 C++ 标准的哪个部分的列表?

是否有任何理由使用 C 而不是 C++ 进行嵌入式开发? [关闭]