当前位置: 首页 > news >正文

Python OrderedDict 用法详解

Python OrderedDict 用法详解

OrderedDict 是 Python 标准库 collections 模块中的有序字典,它记住了键值对的插入顺序,在 Python 3.7+ 中,普通 dict 也保持了插入顺序,但 OrderedDict 仍然有一些独特的功能。

实现原理

OrderedDict 使用 双向链表 + 字典 的复合数据结构实现:
字典:用于存储实际的键值对,提供 O(1) 时间复杂度的查找
双向链表:用于记录键的插入顺序,维护元素顺序关系

基本用法

from collections import OrderedDict# 创建有序字典
od = OrderedDict()
od['a'] = 1
od['b'] = 2
od['c'] = 3print(od)  # OrderedDict([('a', 1), ('b', 2), ('c', 3)])# 按插入顺序迭代
for key, value in od.items():print(key, value)
# 输出:
# a 1
# b 2
# c 3

使用方法

基本操作

  1. OrderedDict([items]) - 构造函数

    from collections import OrderedDict
    od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
    
  2. popitem(last=True) - 移除并返回一个键值对

    • last=True (默认) 移除最后插入的元素 (LIFO)
    • last=False 移除第一个插入的元素 (FIFO)
    od.popitem()  # 移除并返回 ('c', 3)
    
  3. move_to_end(key, last=True) - 将现有键移动到有序字典的任一端

    • last=True (默认) 移动到末尾
    • last=False 移动到开头
    od.move_to_end('a')  # 将 'a' 移动到最后
    

继承自普通字典的方法

OrderedDict 继承了普通字典的所有方法,包括:

  1. clear() - 清空字典

    od.clear()
    
  2. copy() - 创建浅拷贝

    new_od = od.copy()
    
  3. fromkeys(iterable, value=None) - 从可迭代对象创建新 OrderedDict

    od = OrderedDict.fromkeys(['a', 'b', 'c'], 0)
    
  4. get(key, default=None) - 获取键对应的值

    value = od.get('a', 'default')
    
  5. items() - 返回键值对视图 (保持顺序)

    for k, v in od.items():print(k, v)
    
  6. keys() - 返回键视图 (保持顺序)

    for k in od.keys():print(k)
    
  7. values() - 返回值视图 (保持顺序)

    for v in od.values():print(v)
    
  8. pop(key, default) - 移除指定键并返回值

    value = od.pop('b')
    
  9. setdefault(key, default=None) - 获取键值,如果不存在则设置默认值

    od.setdefault('d', 4)
    
  10. update([other]) - 更新字典

    od.update({'d': 4, 'e': 5})
    

比较操作

  1. ==!= - 顺序敏感的相等比较

    d1 = OrderedDict([('a', 1), ('b', 2)])
    d2 = OrderedDict([('b', 2), ('a', 1)])
    print(d1 == d2)  # False,因为顺序不同
    

其他特性

  • OrderedDict 对象会记住插入顺序,迭代时按插入顺序返回键值对
  • 在 Python 3.7+ 中,普通 dict 也保留了插入顺序,但 OrderedDict 提供了一些额外的顺序相关操作

与普通 dict 的区别

  1. 相等性比较OrderedDict 会考虑顺序,而 dict 不会

    d1 = {'a': 1, 'b': 2}
    d2 = {'b': 2, 'a': 1}
    print(d1 == d2)  # Trueod1 = OrderedDict([('a', 1), ('b', 2)])
    od2 = OrderedDict([('b', 2), ('a', 1)])
    print(od1 == od2)  # False
    
  2. 特殊方法OrderedDict 提供了 move_to_end()popitem() 等特有方法

特有方法

1. move_to_end(key, last=True)

将指定键移动到字典的末尾(默认)或开头

od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])# 将 'b' 移动到最后
od.move_to_end('b')
print(od)  # OrderedDict([('a', 1), ('c', 3), ('b', 2)])# 将 'a' 移动到开头
od.move_to_end('a', last=False)
print(od)  # OrderedDict([('a', 1), ('c', 3), ('b', 2)])

2. popitem(last=True)

移除并返回字典的最后一个(默认)或第一个键值对

od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])# 移除并返回最后一个键值对
print(od.popitem())  # ('c', 3)
print(od)  # OrderedDict([('a', 1), ('b', 2)])# 移除并返回第一个键值对
print(od.popitem(last=False))  # ('a', 1)
print(od)  # OrderedDict([('b', 2)])

实际应用场景

1. 实现 LRU (Least Recently Used) 缓存

from collections import OrderedDictclass LRUCache:def __init__(self, capacity):self.cache = OrderedDict()self.capacity = capacitydef get(self, key):if key not in self.cache:return -1self.cache.move_to_end(key)return self.cache[key]def put(self, key, value):if key in self.cache:self.cache.move_to_end(key)self.cache[key] = valueif len(self.cache) > self.capacity:self.cache.popitem(last=False)

2. 保持配置项的顺序

config = OrderedDict()
config['host'] = 'localhost'
config['port'] = 8080
config['debug'] = True# 保持配置项的顺序
for key, value in config.items():print(f"{key}: {value}")

注意事项

  1. 在 Python 3.7+ 中,普通 dict 也保持了插入顺序,但 OrderedDict 仍然在以下情况更有用:

    • 需要明确表示顺序很重要
    • 需要使用 move_to_end() 等方法
    • 需要与旧版 Python 兼容
  2. OrderedDict 比普通 dict 占用更多内存

  3. 在 Python 3.8+ 中,reversed() 可以直接用于 OrderedDict

    od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
    for key in reversed(od):print(key)  # 输出: c, b, a
    

OrderedDict 是处理需要保持插入顺序或需要特殊顺序操作的字典数据的理想选择。

http://www.xdnf.cn/news/1077067.html

相关文章:

  • Day 3:Python模块化、异常处理与包管理实战案例
  • A模块 系统与网络安全 第三门课 网络通信原理-3
  • 【C++】inline的作用
  • 若依中复制到剪贴板指令的使用v-clipboard
  • js严格模式和非严格模式
  • 【Python基础】13 知识拓展:CPU、GPU与NPU的区别和联系
  • 【科研绘图系列】基于R语言的复杂热图绘制教程:环境因素与染色体效应的可视化
  • SeaTunnel 社区月报(5-6 月):全新功能上线、Bug 大扫除、Merge 之星是谁?
  • 基于Spring Cloud微服务架构的API网关方案对比分析
  • 3.1.1.9 安全基线检查项目九:检查是否设置限制su命令用户组
  • [C#] WPF - 自定义样式(Slider篇)
  • 位运算经典题解
  • ELK日志分析系统(filebeat+logstash+elasticsearch+kibana)
  • Python 库 包 nltk (Natural Language Toolkit)
  • 视频断点续播全栈实现:基于HTML5前端与Spring Boot后端
  • 141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示
  • 【Maven 】 <resources> 配置中排除 fonts/** 目录无效,可能是由于以下原因及解决方案:
  • 计算机网络(二)应用层HTTP协议
  • (LangChain)RAG系统链路向量存储之Milvus(四)
  • 【1.4 漫画PostgreSQL高级数据库及国产数据库对比】
  • 【MyBatis保姆级教程下】万字XML进阶实战:配置指南与深度解析
  • 2025年6月28和29日复习和预习(C++)
  • JVM调优实战 Day 15:云原生环境下的JVM配置
  • SQLite与MySQL:嵌入式与客户端-服务器数据库的权衡
  • sqlmap学习ing(2.[第一章 web入门]SQL注入-2(报错,时间,布尔))
  • C++ 第四阶段 STL 容器 - 第九讲:详解 std::map 与 std::unordered_map —— 关联容器的深度解析
  • 解决安装UBUNTU20.04 提示尝试将SCSI(0,0,0),第一分区(sda)设备的一个vfat文件系统挂载到/boot/efi失败...问题
  • poi java设置字体样式
  • 数据结构day4——栈
  • WPF学习笔记(18)触发器Trigger