python OrderedDict 的用法 与 普通dict的区别

它是按照键的插入顺序排序的,更改键对应的值不能改变它的顺序。
它与普通的dict的其中一个区别是 dict.popitem() 会移除最后一个键值对,并返回键值对,不能移除第一个键值对;而OrderedDict的popItem()方法可以移除第一个键值对,并返回该键值对。 用法:排序字典.popitem(last=False)。 然而它默认是删除最后一个键值对并返回
还有一个比较好用的功能是将指定键移动到字典头或者尾部
用法:move_to_end(key, last=True)
将现有 key 移动到有序字典的任一端(头或尾)。 如果 last 为真值(默认)则将元素移至末尾;如果 last 为假值则将元素移至开头。如果 key 不存在则会触发 KeyError:

用法就是可以基于此实现LRU(O(1) 复杂度 put get)

In [14]: site                                                                   
Out[14]: OrderedDict([('n', 1), ('ddd', 2), ('c', 3)])

In [15]: site.popitem(last=False)                                               
Out[15]: ('n', 1)

In [16]: site                                                                   
Out[16]: OrderedDict([('ddd', 2), ('c', 3)])




LRU题目描述如下

运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。
获取数据 get(key) - 如果关键字 (key) 存在于缓存中,则获取关键字的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字/值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。

进阶:

你是否可以在 O(1) 时间复杂度内完成这两种操作?

示例:

LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // 返回  1
cache.put(3, 3);    // 该操作会使得关键字 2 作废
cache.get(2);       // 返回 -1 (未找到)
cache.put(4, 4);    // 该操作会使得关键字 1 作废
cache.get(1);       // 返回 -1 (未找到)
cache.get(3);       // 返回  3
cache.get(4);       // 返回  4



LRU代码如下

from collections import OrderedDict


class LRUCache:
    # 字典头部一直最久未使用,尾部最新
    def __init__(self, capacity: int):
        self.cap = capacity
        self.dict = OrderedDict()

    def get(self, key: int) -> int:
        if key not in self.dict:
            return -1
        else:
            '''
            # pop 删除给定键及其值,并返回该值,没有键则返回默认值
            self.dict.pop(key)
            #  尾部最新
            self.dict[key] = self.dict.pop(key)[1]
            '''
            # 相当于上面两行代码,将指定键值对移到末尾
            self.dict.move_to_end(key)
            return self.dict[key]

    def put(self, key: int, value: int) -> None:
        if len(self.dict) == self.cap:
            if key not in self.dict:
                # 删除最老的
                self.dict.popitem(last=False)
                # 增加值到末尾
                self.dict[key] = value
            # 处理插入重复键
            else:
                self.dict.move_to_end(key)
                self.dict[key] = value
        else:
            # 先移动到末尾,处理重复键
            # 必须加这个if处理空字典
            if key in self.dict:
                self.dict.move_to_end(key)
            self.dict[key] = value


# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)

有用链接:

https://docs.python.org/zh-cn/3/library/collections.html#collections.OrderedDict

你可能感兴趣的:(python)