我有一组(固定的)键,我存储了一个值。我经常查找键的值并递增或递减它。典型的字典用法。
x = {'a': 1, 'b': 4, 'c': 3}
x['a'] += 1
此外,就像递增或递减值一样,我还需要知道第i个最大(或最小)值的关键字。我当然可以进行排序:
s = sorted(x, key=lambda k:(x[k],k))
s[1] == 'c'
问题是每次排序看起来都相当昂贵。特别是因为我只增加了一个项目。我觉得我可以使用另一种更适合这种情况的数据结构。也许一棵树?
答案 0 :(得分:2)
您可以使用blist的sorteddict来保持值的顺序。这是一个字典的快速实现,当迭代时,按照其值的顺序返回其键(未经过密集测试):
import collections
from blist import sorteddict
class ValueSortedDict(collections.MutableMapping):
def __init__(self, data):
self._dict = {}
self._sorted = sorteddict()
self.update(data)
def __getitem__(self, key):
return self._dict[key]
def __setitem__(self, key, value):
# remove old value from sorted dictionary
if key in self._dict:
self.__delitem__(key)
# update structure with new value
self._dict[key] = value
try:
keys = self._sorted[value]
except KeyError:
self._sorted[value] = set([key])
else:
keys.add(key)
def __delitem__(self, key):
value = self._dict.pop(key)
keys = self._sorted[value]
keys.remove(key)
if not keys:
del self._sorted[value]
def __iter__(self):
for value, keys in self._sorted.items():
for key in keys:
yield key
def __len__(self):
return len(self._dict)
x = ValueSortedDict(dict(a=1, b=4, c=3))
x['a'] += 1
print list(x.items())
x['a'] += 10
print list(x.items())
x['d'] = 4
print list(x.items())
这给出了:
[('a', 2), ('c', 3), ('b', 4)]
[('c', 3), ('b', 4), ('a', 12)]
[('c', 3), ('b', 4), ('d', 4), ('a', 12)]
答案 1 :(得分:0)
使用操作员:
import operator
max(x.iteritems(), key=operator.itemgetter(1))[0]
来自文档:
operator.itemgetter(*项目)
返回一个可调用对象,该对象使用。从其操作数中获取项 操作数的 getitem ()方法。如果指定了多个项目, 返回一个查找值元组。例如:
如果它是最好的解决方案,我不知道但是它有效。
答案 2 :(得分:0)
为什么不使用Counter
中的collections
?然后,您可以使用Counter.most_common()
获取排序列表。
>>> from collections import Counter
>>> x = Counter({'a': 1, 'b': 4, 'c': 3})
>>> x['a'] += 1
>>> x.most_common()
[('b', 4), ('c', 3), ('a', 2)]
答案 3 :(得分:0)
您可以使用OrderDict
中的collections
。虽然它在旧的python版本中不可用。
from collections import OrderedDict
如果您安装了django,则可以使用django.utils.datastructures.SortedDict
答案 4 :(得分:0)
我认为大多数python结构都会执行与您在示例中所做的类似的操作。我能想到的唯一能让它更有效的方法就是保留一个按键的排序列表。这样你每次插入时都只需要排序。在您的方法中,每次要按索引访问值时都必须进行排序。这是一个例子:
x = {'a': 1, 'b': 4, 'c': 3}
x['a'] += 1
keyList = sorted(x.keys())
print x[keyList[1]]
4
x['e'] = 7
x['j'] = 11
x['d'] = 6
x['h'] = 8
keyList = sorted(x.keys())
print x[keyList[3]]
6
print x[keyList[4]]
7
希望有所帮助。