是否有 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<int>
如何使用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++ 树容器(map
、set
、multimap
、multiset
)等价物的一般性讨论,请参阅 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<int>
(或unordered_multiset<int>
):
from collections import Counter
def multiset(array):
return set(Counter(array).items())
【讨论】:
以上是关于是否有 C++“multiset<int>”的 Python 等价物?的主要内容,如果未能解决你的问题,请参考以下文章