我有一个OrderedDict结构,通过键排序按以下方式排序:
from collections import OrderedDict
my_regular_dict = {
'1': 'first value',
'2': 'second value',
'3': 'third value'
}
my_ordered_dict = OrderedDict(sorted(my_regular_dict.items(), key=lambda t: t[0]))
在my_ordered_dict
中我希望能够调用给定键的方法,返回下一个键,但在Python 3.5中,这样的话:
>>> my_ordered_dict.get_next_key('1')
'2'
我知道以前在python 3.4和其他人中你可以访问地图并且只是抓住密钥没有问题,但是在python 3.5中使用新的基于C的实现改变了,不可能访问私有方法。
我一直拖着我的头几个小时了,我无法绕过它,有没有办法做到这一点,或者我这样做是错的?
答案 0 :(得分:0)
可能效率不高,因为index
方法(可以使用bisect
进行改进,因为密钥在您的情况下排序),并且还因为在每次调用时创建了一个列表(可以通过循环使用记忆效应迭代键来避免与前一个元素进行比较并返回当前元素,但这是我的建议:
from collections import OrderedDict
def gnk(self, k):
l = list(self.keys())
i = l.index(k)
if i<len(l)-1:
return l[i+1]
else:
raise Exception("last key")
OrderedDict.get_next_key = gnk
my_regular_dict = {
'1': 'first value',
'2': 'second value',
'3': 'third value'
}
my_ordered_dict = OrderedDict(sorted(my_regular_dict.items())) # no need for custom key, keys cannot be equal
print(my_ordered_dict.get_next_key('1'))
它向OrderedDict
类添加了一个方法,它将键创建为列表(不是非常有效,我承认)然后查找键的索引并获取下一个索引。
也许不是你要找的东西,因为它是O(n)
没有bisect
,只有在使用字典顺序对键进行排序时才能使用。
编辑:使用bisect
,O(log(n))
复杂度的方法(但键2列表仍为O(n)
:
import bisect
def gnk(self, k):
l = list(self.keys())
i = bisect.bisect_left(l,k)
if i<len(l)-1:
if l[i]!=k:
raise KeyError(k)
return l[i+1]
else:
raise Exception("last key")
正如一些评论暗示的那样,该解决方案可能无法在Python 3.6+中运行,因此更好的方法是使用bisect
实现自定义字典类进行查找,并实现真正的{{1}为钥匙。编写这样一个类是可行的(但是如果你真的想要密切地模拟一个字典,那么需要时间来微调)但超出了简洁的答案。