Is there a Python equivalent for C++ “multiset<int>”?

妖精的绣舞 提交于 2019-12-18 03:58:29

问题


I am porting some C++ code to Python and one of the data structures is a multiset, but I am not sure how to model this in Python.

Let ms be the C++ multiset<int>

How ms is used (posting some examples)

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

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

回答1:


There isn't. See Python's standard library - is there a module for balanced binary tree? for a general discussion of the equivalents of C++ tree containers (map, set, multimap, multiset) in Python.

The closest I can think of is to use a dictionary mapping integers to counts (also integers). However this doesn't get you the keys in order, so you can't search using lower_bound. An alternative is a to use an ordered list, as suggested by others already, maybe a list of (integer, count) tuples? If you only need to search after you've done all your insertions, you could use the dictionary as a temporary structure for construction, build the list after you've done all the insertions, then use the list for searching.




回答2:


There are a couple implementations of sorted list data types which would fit your criteria. Two popular choices are SortedContainers and blist modules. Each of these modules provides a SortedList data type which automatically maintains the elements in sorted order and would allow for fast insertion and lower/upper bound lookups. There's a performance comparison that's helpful too.

The equivalent code using the SortedList type from the SortedContainers module would be:

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()

All of those operations should work efficiently on a sorted list data type.




回答3:


There are a couple of data-structures which come close.

  • python collections:

    • Ordered dict: dict subclass that remembers the order entries were added. link
    • Counter: dict subclass for counting hashable objects. link
  • provided by django framework:

    • A dict with multiple keys with same value: link
    • Sorted dict which is deprecated as python collection includes an ordered dict now: link



回答4:


You can keep a list ordered using the bisect functions. For example find will become

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

You will find other equivalents in the docs. Instead of checking against end you will now get a ValueError



来源:https://stackoverflow.com/questions/17346905/is-there-a-python-equivalent-for-c-multisetint

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!