python – 使用迭代器协议访问已排序的字典

我有一个词典’vcomments’,其中键是非连续的整数.在循环键时,我需要按排序或反向排序顺序执行此操作.目前我用

for key_pt in sorted(self.view.vcomments.iterkeys()):

但我还需要找到超出或超过某个数字的那些键(或下一个键):

    if direction == 'down':
        sorted_pts = (key_pt for key_pt in sorted(self.view.vcomments.iterkeys()) if key_pt > curr_pt)
    else:
        sorted_pts = (key_pt for key_pt in reversed(sorted(self.view.vcomments.iterkeys())) if key_pt < curr_pt)
    try:
        next_pt = sorted_pts.next()
    except StopIteration:

>我是否可以创建一个迭代器类(使用迭代器协议)来存储字典并使我能够以正向或反向顺序循环它们?我假设/猜测我可能需要首先分配一个属性值,该值将指示下一个循环是否应该是正向/反向.
>我可以在我的迭代器类中包含一个生成器函数(嵌套),使我能够检索下一个键;也就是说,在提供的整数之前或之前?
>同样,我是否有办法提供开始和结束点并检索落在这些值之间的所有键(按排序顺序)?

我为问三个(虽然是相关的)问题而道歉 – 对第一个问题的回答会给我一个开始.而且我没有足够的粗暴期待一个完整的解决方案,只是表明这些对我来说是否可行.

补充:我仍然需要能够通过其密钥检索单个特定字典项.

最佳答案 我认为这里最适合您需求的数据结构是
skip list.我从来没有实现过 – 总是想要 – 但它看起来像我拥有你需要的所有东西.

>跳过列表按排序顺序存储其项目.使基本列表成为双向链表将允许在O(n)中进行正向和反向迭代.
>跳过列表允许O(log n)插入,修改,删除和搜索.这并不像字典那么快,但在我看来,如果你需要按排序顺序存储的项目,字典会给你带来麻烦 – 甚至是OrderedDict,除非你很少添加密钥.
>通过上面维基百科文章中描述的一些修改,甚至索引访问也可以在O(log n)中实现.

Python here中有一个实现 – 可能还有其他一些实现.

但是,您的一些评论表明您可能满足于简单地迭代字典的排序副本,而您只是想清理上面的代码.所以这是一种方法.这很天真,但这是一个起点.这假设你完全没有O(n)搜索时间和O(n log n)迭代次数,这两次都不是最理想的……

>>> class SortIterDict(dict):
...     def __iter__(self):
...         return iter(sorted(super(SortIterDict, self).__iter__()))
...     def __reversed__(self):
...         return reversed(tuple(iter(self)))
...     def get_next(self, n):
...         return next((x for x in iter(self) if x > n), None)
...     def get_prev(self, n):
...         return next((x for x in reversed(self) if x < n), None)
... 
>>> d = SortIterDict({'d':6, 'a':5, 'c':2})
>>> list(d)
['a', 'c', 'd']
>>> list(reversed(d))
['d', 'c', 'a']
>>> d.get_next('b')
'c'
>>> d.get_prev('b')
'a'
点赞