作者:@欧礼图
本文章出自企划:麻瓜指南,一个创作者互帮互助共同创作的企划。联系方式见文末尾。
众所周知,字典的一大特性就是元素是无序排列的。那想让字典记住元素的插入顺序该怎么做呢?这就需要用到有序字典这一数据结构了。在正式介绍前,有一点需要读者注意:有序并不是指字典里的元素会按照大小顺序排列,而是说字典会记住所有元素插入的顺序,类似于链表。现在我们就来详细讲解一下有序字典都有什么功能,以及你应该怎么来使用它。
有序字典
定义:python有序字典通常指collections
库里的OrderedDict
类。它继承python的dict
类,也就意味着它和普通字典的使用方法相同,但在某些方法上有所差异。
使用及方法:
popitem(*last*=True)
popitem
函数原是字典内置函数,作用是返回并删除字典中最后一个元素。在OrderedDict
里,该函数支持传入last
关键字,当last=True
时作用与普通字典相同,last=False
时改为返回并删除字典首个元素。示例如下:1
2
3
4
5
6
7
8from collections import OrderedDict
'law') test_ordered_dict = OrderedDict.fromkeys(
test_ordered_dict
OrderedDict([('l', None), ('a', None), ('w', None)])
False) test_ordered_dict.popitem(last=
('l', None) # 删除为字典首个元素
True) test_ordered_dict.popitem(last=
('w', None) # 删除为字典末位元素move_to_end(*key, last*=True)
该函数为
OrderedDict
独有函数,作用为将指定键值对应元素移到首位或末尾。当last=False
时,移除首个元素。last=True
时,移除末位元素。示例如下:1
2
3
4
5
6
7
8from collections import OrderedDict
'law') test_ordered_dict = OrderedDict.fromkeys(
'w', last=False) test_ordered_dict.move_to_end(
test_ordered_dict
OrderedDict([('w', None), ('l', None), ('a', None)])
'w', last=True) test_ordered_dict.move_to_end(
test_ordered_dict
OrderedDict([('l', None), ('a', None), ('w', None)])
拓展阅读:更多OrderedDict
特性可在官网查看
有序集合
概述:有序集合可以利用有序字典中fromkeys
函数创建,我们可以将元素转化为key: None
的键值对。示例如下:
1 | from collections import OrderedDict |
除此之外,一些python第三方库提供了有序集合的实现。这里提供一些参考:
ordered-set、
orderedset (Cython based)、boltons-IndexedSet。
结语
在python3.7之后,普通字典也支持记住元素的插入顺序。那我们以后就可以用普通字典来代替有序字典了吗?答案很显然是否定的。除了上述多出的方法之外,如果我们想比较两个字典是否相等,有序字典还会自动检查元素的插入顺序。即使两个有序字典内容完全一样,如果插入顺序有所差异,这两个有序字典便不会判定为相等。更多差异请参考官网。
我的补充
Ordered Dict
PEP520: Preserving Class Attribute Definition Order
PEP372: Adding an ordered dictionary to collections
PEP372给python提供了OrderedDict类。之后的字典默认保留了顺序,没有走哈希。
Ordered Set
集合是哈希的顺序。
整数作为集合的元素时,位置比较稳定。但是理论上是没有顺序的。
Cython里有OrderedSet。然后这里有一个第三方ordered-set 4.0.2仓库,里面也有一个OrderedSet,兼容了numpy对象。
难道是新版本的python会整合orderedSet和Set类,使Set默认保留顺序?
也可能是社区上谁提了一嘴。