【编程课堂】有序字典 OrderedDict

编程课堂将和每周一坑一样,成为本教室公众号的一个长期固定栏目。每期讲解一个编程知识点,包括但不限于 Python 语法、模块介绍、编程小技巧等。用简短的篇幅,让你多了解一点编程。

上周每周一坑的题目 三门问题 将在本周讲解,还没有看过的同学赶紧的。


在我们的 Python 入门系列文章中,有介绍过字典 dict:【Python 第37课】 字典。其中有简单提及到,字典中的键值对是没有顺序的,所以无法像列表或元组一样通过索引来访问元素。

这简单的一笔带过恐怕不能引起注意,那么来看这个例子:

d = {} d['c'] = 3 d['b'] = 2 d['a'] = 1 print(d)

在你的电脑上运行下,看看输出结果是什么?

有的人会是:

{'a': 1, 'b': 2, 'c': 3}

有的人则是:

{'a': 1, 'c': 3, 'b': 2}

如果你改变一下字典赋值的顺序,结果可能没有变化,也可能发生了变化……

dict 的实现方式决定了其是无序的(hash 映射,这里不展开),添加键值对的先后顺序和最终输出显示的顺序没有任何关系。

这一点和 list 是不一样的,在 python shell 中这样试下便可明白:

>>> [1, 2] == [2, 1] False >>> {'a':1, 'b':2} == {'b':2, 'a':1} True

这也导致一些同学在刚刚编写代码时感到困惑:

为什么字典的结果不按照我想要的顺序来?

好在 Python 里提供了一个解决方案:OrderedDict

在官方文档中,可以找到如下描述:

Ordered dictionaries are just like regular dictionaries but they remember the order that items were inserted. When iterating over an ordered dictionary, the items are returned in the order their keys were first added.

简单来说,就是有序字典和普通的字典并无差异,但是它记录了条目添加的顺序,当迭代有序字典时,字典内容随着被添加的顺序返回。

如果你在 python shell 中输入:

>>> from collections import OrderedDict
>>> help(OrderDict)

可以看到第一行写着:

class OrderedDict(__builtin__.dict)

也就是说,OrderedDict 是 dict 的子类。所以你可以放心地像 dict 一样来使用它。而同时,它又增加了对添加顺序的记录:

from collections import OrderedDict d = OrderedDict() d['c'] = 3 d['b'] = 2 d['a'] = 1 print(d)

无论在什么环境下,输出结果都是:

OrderedDict([('c', 3), ('b', 2), ('a', 1)])

如果用 for 循环遍历,一样会保持这个顺序:

for key in d:    print(key, d[key])

输出(py3):

c 3 b 2 a 1

如果现在你有一个字典,想要对其按照一定的规则进行排序,则可通过 sorted + OrderedDict 来实现:

from collections import OrderedDict d = {'a': 2, 'b': 3, 'c': 1} # 以 value 值对 dic 排序 sd = sorted(d.items(), key=lambda x: x[1]) # 转换为有序字典 od = OrderedDict(sd) print(od)

如此就生成了一个排序后的有序字典。由于是 dict 的子类,所以字典的方法它都可以使用,这里不再赘述。提两个 OrderedDict 新增的方法:

popitem(last=True)

默认去除最后的条目,如果想删除第一条,将 True 改为 False

>>> od.popitem() ('b', 3) >>> od OrderedDict([('c', 1), ('a', 2)])

move_to_end(key, last=True)

(py3中新增)移动 key 对应的条目到顺序末端,last=False 时调整到首位

>>> od.move_to_end('a') >>> od OrderedDict([('c', 1), ('b', 3), ('a', 2)])

关于 OrderedDict 就介绍到这里。你可能已经注意到,OrderedDict 是 collections 模块中的一个类。

collections 是 Python 自带的一个非常好用的模块,在常见的 dict、list、set、tuple 等类型之上,提供了额外的容器数据类型。

之后我们还将会介绍其中的其他实用功能。等不及的同学可以自行搜索相关内容或查阅官方文档。


(0)

相关推荐

  • 原来 collections 这么好用!!

    (给Python开发者加星标,提升Python技能) 来源: 南枝向暖北枝寒MA https://blog.csdn.net/mall_lucy/article/details/108822795 [ ...

  • python入门-------夜曲编程

    python入门-------夜曲编程

  • Python 列表去重的4种方式及性能对比

    列表去重是Python中一种常见的处理方式,任何编程场景都可能会遇到需要列表去重的情况. 列表去重的方式有很多,本文将一一讲解他们,并进行性能的对比. 让我们先制造一些简单的数据,生成0到99的100 ...

  • Python实战013:如何将数据以JSON格式输出

    JSON(全称:JavaScript Object Notation) 是一种轻量级的数据交换格式,它的结构简洁.层次清晰也没有xml那么多标签描述让文件更加小巧且解析速度更快.非常适合做网络传输的数 ...

  • 第30天:Python collections 模块

    第30天:Python collections 模块

  • 4.Python列表/元组/集合/字典

    碧茂大数据 前天 4.1 Python列表 · 列表用 [ ] 标识,是Python 最通用的复合数据类型. · 列表用 [ ] 表示,列表具有可嵌套性 4.1.1 Python列表截取 · 列表可以 ...

  • python字典常见用法总结

    Python字典是另一种可变容器模型,且可存储任意类型对象,如字符串.数字.元组等其他容器模型. 一.创建字典 字典由键和对应值成对组成.字典也被称作关联数组或哈希表.基本语法如下: 注意: 每个键与 ...

  • 从列表或字典创建Pandas的DataFrame对象的方法

    介绍 每当我使用pandas进行分析时,我的第一个目标是使用众多可用选项中的一个将数据导入Pandas的DataFrame . 对于绝大多数情况下,我使用的 read_excel , read_csv ...

  • 【编程课堂】装饰器浅析

    Python 拥有丰富强大的功能和表达特性,其中之一便是装饰器,装饰器能够在不改变函数.方法.类本身的情况下丰富他们的功能. 比如,我们有一个函数 func ,我们希望在不改变函数的前提下记录函数运行 ...

  • 【编程课堂】以 jQuery 之名 - 爬虫利器 PyQuery

    很多读者在学习了 Python 之后都想做一些爬虫程序,去网上采集数据或完成一些自动化操作.因此,我们也制作了一套爬虫实战课程,目前正在最后的完善中,很快将和各位见面. 等不及的朋友,可以先来看看这个 ...

  • 【编程课堂】同一台电脑,不同的 Python

    virtulenv 是一个创建独立 python 运行环境的工具. 在标准的 python 环境中,所有的库都是唯一存在的,不会有两个或以上版本的相同库. 但在日常的开发工作中常常会遇到此类问题,比如 ...

  • 【编程课堂】selenium 祖传爬虫利器

    一些网页,比如微博,只有在登录状态才能进行页面的访问,或者对数据有比较复杂的验证和保护,直接通过网络请求进行登录并获取数据就会比较麻烦.这种时候,就该本篇的主角 selenium 上场了. Selen ...

  • 【编程课堂】jieba-中文分词利器

    0.前言 在之前的文章[编程课堂]词云 wordcloud 中,我们曾使用过 jieba 库,当时并没有深入讲解,所以本次将其单独列出来详细讲解. jieba库是进行中文分词的利器,根据文档描述,具有 ...

  • 【编程课堂】 windows计划任务

    在学习了一些爬虫或者 web 开发等知识之后,常常我们会有这样的需求: 写了个爬取豆瓣电影的脚本,需要每天定时自动运行: 使用 django 开发了一个小小的博客网站,希望开启电脑之后就自动在 CMD ...

  • 【编程课堂】海龟作图

    0.前言 turtle  是 python 内置的一个比较有趣味的模块,俗称 海龟作图,它是基于 tkinter 模块打造,提供一些简单的绘图工具,海龟作图最初源自 20 世纪 60 年代的 Logo ...

  • 【编程课堂】震惊!小 bug 引发大灾难,0.1 + 0.2 的结果竟然是……

    各位观众点进标题看文章的时候,我已经准备打包行李去UC报道啦~ 冷笑话结束,嗯,说正事.请大家思考一下在 python 控制台输入  0.1 + 0.2 == 0.3 ,返回的结果是什么?手边有电脑的 ...

  • 【编程课堂】计数器 Counter

    上一期的编程课堂我们介绍了 有序字典 OrderedDict,这一期我们再来聊聊 同属 collections 模块的另一种数据类型 Counter. 在了解 Counter 之前,请大家思考一个问题 ...