如何从字典中删除最旧的元素?

时间:2009-11-18 15:56:50

标签: python dictionary

我想了解删除字典中最旧元素的最佳方法,以便控制字典的最大大小。

示例

MAXSIZE = 4
dict = {}
def add(key,value):
  if len(dict) == MAXSIZE:
    old = get_oldest_key() # returns the key to the oldest item
    del dict[old]
  dict[key] = value

add('a','1') # {'a': '1'}
add('b','2') # {'a': '1', 'b': '2'}
add('c','3') # {'a': '1', 'c': '3', 'b': '2'}
add('d','4') # {'a': '1', 'c': '3', 'b': '2', 'd': '4'}
add('e','5') # {'c': '3', 'b': '2', 'e': '5', 'd': '4'}

这是清楚的吗?

修改:忘记len(dict)落后一项。

9 个答案:

答案 0 :(得分:12)

Python 3.1有一个有序的字典。使用类collections.OrderedDict来保持元素的插入顺序。请注意,如果您要覆盖一个元素,它会保持在顺序中的位置,您需要删除并重新插入一个元素以使其持久。

如果您使用的是旧版本,则可以使用补丁来获取OrderedDict。

无论如何,如果它不可用,你可以简单地使用一个元组列表:它可以很容易地从字典转换成字典,保持其排序,可以像append和{{pop的队列一样使用1}},...

答案 1 :(得分:7)

字典不保留顺序,因此您无法分辨首先添加了哪个元素。您可以将字典与其密钥列表组合以保留顺序。

这是一个activestate recipe,用于执行此操作的有序字典。

还有PEP-0372这个patch用于冒险类。

答案 2 :(得分:3)

除非你有一些设定数量的元素,你知道哪一个是最老的元素,那么你可以简单地删除它。否则,你正在使用错误的数据结构来实现我的想法。

编辑:虽然,根据一个快速的谷歌,我遇到this.哦,我喜欢collections模块:)

答案 3 :(得分:3)

执行此操作的一种方法是将密钥存储在一个数组中,这将保留您的订单。类似的东西:

MAXSIZE = 4
dict = {}
history = []
def add(key,value):
    print len(dict)
    if len(dict) == MAXSIZE:
        old = history.pop(0) # returns the key to the oldest item
        del dict[old]
    history.append(key)
    dict[key] = value

另外,请注意len()总是落后于一个项目。当您添加第五项时,len(dict)4,而不是5。您应该使用==代替>

答案 4 :(得分:3)

我相信LRU dict-like container会满足您的需求。

答案 5 :(得分:1)

或者也可以使用元组列表。

MAXSIZE = 4
stack = []

def add(key, value):
 stack.append((key, value))
 if len(stack) > MAXSIZE:
  stack.pop(0)

 print stack

add('a','1')
add('b','2')
add('c','3')
add('d','4')
add('e','5')

结果

[('a', '1')]
[('a', '1'), ('b', '2')]
[('a', '1'), ('b', '2'), ('c', '3')]
[('a', '1'), ('b', '2'), ('c', '3'), ('d', '4')]
[('b', '2'), ('c', '3'), ('d', '4'), ('e', '5')]

请注意,使用此方法确实会降低字典查找的速度。因此,如果您需要定制的有序字典可能是有序的。

您可以找到pocoo团队here的实施。我总是觉得他们的工作很出色。

答案 6 :(得分:1)

Python字典现已订购(从3.6及更高版本开始)。 more details
next(iter(dict))将给出最早的(或第一个)密钥。 stackoverflow answer

因此,要删除最早的(或第一个)密钥,我们可以使用以下...

dict.pop(next(iter(dict)))

答案 7 :(得分:0)

不知道你真正想要使用这个结构的是什么,这里是 可能对你有用的东西:

class DictCache:
    def __init__(self, maxcount=4):
        self.data = {}
        self.lru = []
        self.maxcount = maxcount
    def add(self, key, value):
        self.data[key] = value
        self.lru.append(key)
        if len(self.lru) > self.maxcount:
            dead = self.lru.pop(0)
            del(self.data[dead])

将此与重新排列get的{​​{1}}方法相结合 当他们被访问时,您可以更改您的缓存策略以适应您的 用例。

答案 8 :(得分:0)

这是怎么回事?将命令放在数组中,当达到限制时,弹出它。

MAXSIZE = 4
dict,order= {},[]

def add(key,value):
    if len(dict) > MAXSIZE:
        old = order.pop() # returns the key to the oldest item
        del dict[old]
    order.insert(0,key)
    dict[key] = value