Python3 CookBook | 数据结构和算法(一)
来源:互联网 发布:vray for c4d r18 mac 编辑:程序博客网 时间:2024/05/22 10:35
文章首发于知乎专栏,欢迎关注。
https://zhuanlan.zhihu.com/pythoncookbook
以下测试代码全部基于 Python3。
Python 提供了大量的内置数据结构,包括列表,集合以及字典。在工作和编码中,可以说天天和它们打交道,经常碰到查询,排序和过滤等等这些问题,虽然每次解决这些问题并不困难,但总感觉代码写的很麻烦,不够优雅。
最近通过阅读《Python3 CookBook》,了解了一些更优秀的方法,做一些简单记录,与大家分享。
1、解压可迭代对象赋值给多个变量
我们都知道,一个序列是可以赋值给多个变量的,就像下面这样:
In [7]: p = (1, 2, 3)In [8]: x, y, z = pIn [9]: xOut[9]: 1
但如果接收的变量个数和序列元素个数不一致,就会报错,如果你不知道元素个数的话,可以采用下面这样的方式:
In [10]: x, *y = pIn [11]: yOut[11]: [2, 3]
通过这种星号的方式,就可以解压不确定个数或任意个数的可迭代对象了,是不是很棒呢?
那么,用这个方法可以解决哪些问题呢?
先来看一种情况,现在有一个序列,去掉第一个数和最后一个数,然后求剩下数的平均值。
这个问题很简单,我的第一反应是循环求和,然后计算平均值,显然很麻烦。这时候星号表达式就派上用场了:
def drop_first_last(items): first, *middle, last = items return avg(middle)
再看一种情况,比如字符串的分割:
In [12]: line = 'drwxr-xr-x 41 zyx staff 1.4K 11 24 08:53 zyx'In [13]: info, *fields, homedir = line.split(' ')In [14]: infoOut[14]: 'drwxr-xr-x'In [15]: homedirOut[15]: 'zyx'
2、保留最后 N 个元素
这个问题也是经常会遇到的,比如只取文件中满足要求的前五行,或者只返回满足要求的最新十条数据。我的第一反应是列表,然后通过 push 和 pop 来操作列表来实现。
其实通过 collections.deque 可以很容易解决这个问题,使用 deque(maxlen=N) 构造函数新建一个固定大小的队列。当新元素加入并且这个队列已满时,最先进入队列的元素便会被移除,符合先进先出的原则。
In [16]: from collections import dequeIn [17]: q = deque(maxlen=3)In [18]: q.append(1)In [19]: q.append(2)In [20]: q.append(3)In [21]: qOut[21]: deque([1, 2, 3])In [22]: q.append(4)In [23]: qOut[23]: deque([2, 3, 4])
如果没有设置 maxlen 则是一个无限大小的队列,可以通过 appendleft 和 pop 在队首和队尾添加删除元素。
3、字典中的键映射多个值
现在有一个需求,构建一个字典,key 是用户 ID,value 为一个列表,列表元素可以是名字,电话等等,大概是这样:
d = {'id': ['name', 'phone']}
如果我们自己构建这个字典,可能会像下面这样来实现:
d = {}for key, value in items: if key not in d: d[key] = value d[key].append(value)
很麻烦,如果使用 collections 的 defaultdict 就很简单了。defaultdict 的一个特征就是它会自动初始化每个 key 刚开始对应的值,所以我们只关注添加元素操作就可以了。
优化后代码就变成了这样:
d = defaultdict(list)for key, value in items: d[key].append(value)
4、字典排序
字典是无序的,但如果要控制字典中元素的顺序呢?可以使用 colletions 中的 OrderedDict,如下:
d = OrderedDict()d['foo'] = 1d['bar'] = 2d['spam'] = 3d['grok'] = 4# Outputs "foo 1", "bar 2", "spam 3", "grok 4"for key in d: print(key, d[key])
OrderedDict 内部维护这一个根据键插入顺序排序的双向链表。每次新元素插入时,便会被放在链表尾部,对于已经存在的键,并不会改变键的顺序。
但需要注意的是,OrderedDict 的大小是普通字典的两倍,所以在构建一个需要大量 OrderedDict 实例的数据结构时,就要考虑大量内存消耗的影响了。
5、字典的运算
如何取出字典中的最小值,或者对字典进行排序呢?
首先我们来看看直接使用普通的数学运算函数
In [25]: d = {'a': 11, 'b': 43, 'c': 3, 'd': 65}In [26]: min(d)Out[26]: 'a'
它比较的逻辑是直接比较 key,然后取出对应的 key,但如果要比较 value 呢?
In [28]: min(d.values())Out[28]: 3
结果是正确的,但似乎并不完美,如果键值一起返回就完美了。这时候就该 zip 登场了,它的作用是可以使键和值反转过来。
In [29]: min(zip(d.values(), d.keys()))Out[29]: (3, 'c')
它直接返回了值最小的键和值,这样就很好了,不管需要哪个信息都可以直接使用。如果要对这个字典排序的话也很简单:
In [34]: sorted(zip(d.values(), d.keys()))Out[34]: [(3, 'c'), (11, 'a'), (43, 'b'), (65, 'd')]
先写这么多吧,未完待续。。。
欢迎留言,或者添加我个人微信 zhangyx6a 交流沟通,不是微商。
- Python3 CookBook | 数据结构和算法(一)
- Python3 CookBook | 数据结构和算法(二)
- Python3 cookbook学习笔记-数据结构与算法1
- Python3 cookbook学习笔记-数据结构与算法2
- Python3 cookbook学习笔记-数据结构与算法3
- Python3 cookbook学习笔记-数据结构与算法4
- Python3 cookbook学习笔记-数据结构与算法5
- Python3 cookbook学习笔记-数据结构与算法6
- python cookbook:第一章 数据结构和算法
- Python3 CookBook | 日期和时间
- 数据结构和算法分析实验(一)
- 数据结构和算法总结(一)
- 数据结构和算法概览(一)
- 【Java】Java数据结构和算法(一)
- 数据结构和算法分析(一) 引论
- js数据结构和算法(一)概述
- python 数据结构和算法(一)
- Java数据结构和算法(一)--前言
- 整数划分问题算法 能看得懂的 详解
- Kafka Consumer Java API实现
- 线段树区间更新
- 57 Insert Interval
- BZOJ3835: [Poi2014]Supercomputer
- Python3 CookBook | 数据结构和算法(一)
- 【TensorFlow】MNIST(使用softmax)
- fresco加载图片+EventBus Activity之间跳转传值+GreenDAo数据库+retrofit请求数据+recyclerview展示数据+ButterKnife找控件
- Aerospike 的索引内存管理--as_index->dim
- 索引查找(分块查找)
- 3
- 第一周 枚举 例题4.称硬币 [POJ1013]
- 关于线索二叉树恢复成正常二叉树
- C#实现自动升级(附源码)