python3-cookbook笔记:第一章 数据结构和算法
python3-cookbook中每个小节以问题、解决方案和讨论三个部分探讨了Python3在某类问题中的最优解决方式,或者说是探讨Python3本身的数据结构、函数、类等特性在某类问题上如何更好地使用。这本书对于加深Python3的理解和提升Python编程能力的都有显著帮助,特别是对怎么提高Python程序的性能会有很好的帮助,如果有时间的话强烈建议看一下。
本文为学习笔记,文中的内容只是根据自己的工作需要和平时使用写了书中的部分内容,并且文中的示例代码大多直接贴的原文代码,当然,代码多数都在Python3.6的环境上都验证过了的。不同领域的编程关注点也会有所不同,有兴趣的可以去看全文。
python3-cookbook:https://python3-cookbook.readthedocs.io/zh_CN/latest/index.html
1.2 解压可迭代对象赋值给多个变量
此小节主要是对于星号表达式的探讨,当想要将一个可迭代对象的部分元素赋值给某个变量,尤其是这部分元素的数量并不确定时,星号表达式就能很好的排上用场了。
使用场景1:普通的分割赋,需要注意的是,星号表达式的变量为列表类型,即使该变量中的元素为0个。
>>> record = ('Dave', 'dave@example.com', '773-555-1212', '847-555-1212')
>>> name, email, *phone_numbers = record
>>> name
'Dave'
>>> email
'dave@example.com'
>>> phone_numbers
['773-555-1212', '847-555-1212']
>>> name, email, phone_number1, phone_number2, *others = record
>>> others
[]
>>>
使用场景2:在迭代元素为可变长序列时,星号表达式也很好用。
records = [
('foo', 1, 2),
('bar', 'hello'),
('foo', 3, 4),
] def do_foo(x, y):
print('foo', x, y) def do_bar(s):
print('bar', s) for tag, *args in records:
if tag == 'foo':
do_foo(*args)
elif tag == 'bar':
do_bar(*args)
1.3 保留最后 N 个元素
在迭代操作或者其他操作中,如果想要保留一个有固定元素个数的对象的时候,可以考虑使用collections.deque,它会构造一个固定长度的队列(如果指定了的话),当队列满了之后,如果继续往队列中添加元素,就会删除最老的元素,再添加新的元素进去。deque也有对应的方法在队列的两端添加和弹出元素。虽然可以使用列表等方法实现相同的功能,但deque的性能上是优于列表的插入删除等操作的,当然,具体的场景还是要看个人的使用习惯和选择了,此小节只是给出了另一个值得考虑的解决方案。
>>> from collections import deque
>>> q = deque(maxlen=3)
>>> q.append(1)
>>> q.append(2)
>>> q.append(3)
>>> q
deque([1, 2, 3], maxlen=3)
>>> q.append(4)
>>> q
deque([2, 3, 4], maxlen=3)
>>> q.appendleft(5)
>>> q
deque([5, 2, 3], maxlen=3)
>>> q.pop()
3
>>> q
deque([5, 2], maxlen=3)
>>> q.popleft()
5
>>> q
deque([2], maxlen=3)
>>>
1.4 查找最大或最小的 N 个元素
在一个元素个数比较多的集合中查找最大或最小的N个元素,并且要查找的元素个数相对于集合本身元素个数较小时,可以考虑使用heapq模块中的nlargest和nsmallest函数。需要注意的是如果要查找的元素个数和集合本身的元素个数相近的话,建议使用先排序后切割的方式,如sorted(items)[:N]。
在heapq中,由于它是堆结构的,所以第一个元素永远是最小的,当你想要多次使用集合,并且每次使用集合时可以得到集合的最小元素时,可以考虑使用heapq模块,当然,如果你仅仅是想要得到该集合中的唯一一个最大或最小的元素时,建议直接使用max或min函数。
>>> import heapq
>>> nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
>>> heapq.nlargest(3, nums)
[42, 37, 23]
>>> heapq.nsmallest(3, nums)
[-4, 1, 2]
>>> portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
>>> heapq.nlargest(3, portfolio, key=lambda s: s['price'])
[{'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'ACME', 'shares': 75, 'price': 115.65}, {'name': 'IBM', 'shares': 100, 'price': 91.1}]
>>>
>>> heap = list(nums)
>>> heapq.heapify(heap) # 将数据进行堆排序后放入列表中
>>> heap
[-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8]
>>> heapq.heappop(heap)
-4
>>> heapq.heappop(heap)
1
>>> heapq.heappop(heap)
2
>>>
1.8 字典的运算
如果想要某个字典中键最大(最小)或值最大(最小)的键值对,可以使用zip()函数将键值先反转过来。
>>> prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
>>> max(zip(prices.values(), prices.keys()))
(612.78, 'AAPL')
>>> min(zip(prices.values(), prices.keys()))
(10.75, 'FB')
>>>
1.11 命名切片
程序中使用下标进行切片的情况还是比较多的,如果下标在使用时写死的话,就会使得程序后期变得难以维护,这时可以考虑将切片的下标换为内置的slice函数,所有的下标切片都可以使用这个函数。
>>> items = [0, 1, 2, 3, 4, 5, 6]
>>> a = slice(2, 4)
>>> items[2:4]
[2, 3]
>>> items[a]
[2, 3]
>>> items[a] = [10, 11]
>>> items
[0, 1, 10, 11, 4, 5, 6]
>>> a.start
2
>>> a.stop
4
>>> a.step
>>>
>>> record = '....................100 .......513.25 ..........'
>>> cost = int(record[20:23]) * float(record[31:37]) # 下标切片写死在代码里,不建议这样做
>>> cost
51325.0
>>> SHARES = slice(20, 23)
>>> PRICE = slice(31, 37)
>>> cost = int(record[SHARES]) * float(record[PRICE])
>>> cost
51325.0
>>>
1.12 序列中出现次数最多的元素
对于一个序列中每个元素的出现次数,当然可以自己手动利用字典去实现,但是最优的选择应该是collections.Counter,它就是专门为这类问题而设计的,Counter对象的底层实现其实也是一个字典,具体使用见示例代码。
>>> from collections import Counter
>>> words = [
'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
'my', 'eyes', "you're", 'under'
]
>>> word_counts = Counter(words)
>>> word_counts.most_common(3) # 出现次数最多的3个单词
[('eyes', 8), ('the', 5), ('look', 4)]
>>> word_counts['eyes']
8
>>> morewords = ['why','are','you','not','looking','in','my','eyes']
>>> for word in morewords:word_counts[word] += 1 # 像字典一样操作Counter对象 >>> word_counts['eyes']
9
>>> word_counts.update(morewords) # 或者使用update方法进行更新
>>> a = Counter(words)
>>> b = Counter(morewords)
>>> c = a + b # 可以使用+/-运算符进行操作
>>> c
Counter({'eyes': 9, 'the': 5, 'look': 4, 'my': 4, 'into': 3, 'not': 2, 'around': 2, "don't": 1, "you're": 1, 'under': 1, 'why': 1, 'are': 1, 'you': 1, 'looking': 1, 'in': 1})
>>>
1.13 通过某个关键字排序一个字典列表
如果想要对一个元素为字典的列表进行排序操作,如sorted/max/min等函数,平常使用对应的lambda表达式即可,但是如果对性能有要求的话,建议使用operator.itemgetter函数。
如果排序的元素不是字典,而是类对象,则可以使用operator.attrgetter,这是1.14节的内容,用法与itemgetter相似,就不贴示例代码了。
>>> from operator import itemgetter
>>> rows = [
{'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
{'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
]
>>> sorted(rows, key=itemgetter('fname'))
[{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
>>> sorted(rows, key=itemgetter('lname','fname'))
[{'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}, {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}]
>>>
1.20 合并多个字典或映射
当你想在多个字典中查找某些键或值的时候可以使用collections.ChainMap,它会将多个字典从逻辑上合并为一个字典,如果多个字典中有相同的键,则对于该键的操作总是对应的拥有该键的第一个字典。需要注意的是对于ChainMap对象的操作是会作用到对应的字典上去的。
>>> from collections import ChainMap
>>> a = {'x': 1, 'z': 3 }
>>> b = {'y': 2, 'z': 4 }
>>> c = ChainMap(a,b)
>>> c['x']
1
>>> c['y']
2
>>> c['z']
3
>>> len(c)
3
>>> list(c.keys())
['x', 'z', 'y']
>>> list(c.values())
[1, 3, 2]
>>> c['z']
3
>>> c['z'] = 10
>>> c['z']
10
>>> c['w'] = 40
>>> c['w']
40
>>> a
{'x': 1, 'z': 10, 'w': 40}
>>>
python3-cookbook笔记:第一章 数据结构和算法的更多相关文章
- C++ Primer 笔记 第一章
C++ Primer 学习笔记 第一章 快速入门 1.1 main函数 系统通过调用main函数来执行程序,并通过main函数的返回值确定程序是否成功执行完毕.通常返回0值表明程序成功执行完毕: ma ...
- Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式
Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...
- Android群英传笔记——第一章:Android体系与系统架构
Android群英传笔记--第一章:Android体系与系统架构 图片都是摘抄自网络 今天确实挺忙的,不过把第一章的笔记做一下还是可以的,嘿嘿 1.1 Google的生态圈 还是得从Android的起 ...
- 《SQL CookBook 》笔记-第一章-检索记录
目录 第一章 检索记录 1.1检索所有行和列 1.2筛选行 1.3查找满足多个查询条件的行 1.4筛选列 1.5创建列的别名 1.6 在where子句中引用别名列 1.7 串联多列的值 1.8 在se ...
- 重温《STL源码剖析》笔记 第一章
源码之前,了无秘密. --侯杰 经典的书,确实每看一遍都能重新收获一遍: 第一章:STL简介 STL的设计思维:对象的耦合性极低,复用性极高,符合开发封闭原则的程序库. STL的价值:1.带给我们一套 ...
- [编程笔记]第一章 C语言概述
//C语言学习笔记 第一讲 C语言概述 第二讲 基本编程知识 第三讲 运算符和表达式 第四讲 流程控制 第五讲 函数 第六讲 数组 第七讲 指针 第八讲 变量的作用域和存储方式 第九讲 拓展类型 第十 ...
- 《css3实战》读书笔记 第一章 基于CSS需求而编写的HTML.
笔记说明 <CSS3实战手册第3版(影印版)>可以消除Web设计工作的痛苦,并且带给你:HTML--重新入门.如果你是HTML新手,你会学到如何以CSS友好的方式进行基本页面构造.若你是H ...
- 读阮一峰老师 es6 入门笔记 —— 第一章
鉴于最近用 vuejs 框架开发项目,其中有很多涉及到 es6 语法不太理解所以便认真地读了一下这本书. 地址:http://es6.ruanyifeng.com/#README 第一章:let ,c ...
- 【js 笔记】读阮一峰老师 es6 入门笔记 —— 第一章
鉴于最近用 vuejs 框架开发项目,其中有很多涉及到 es6 语法不太理解所以便认真地读了一下这本书. 地址:http://es6.ruanyifeng.com/#README 第一章:let ...
随机推荐
- 底层解析web安全软件
试用了一些 web安全软件,服务器安全狗.云锁.绿盟…… 感觉里面有些功能是可以手动优化的,大概总结一下. 1.禁止 ping 这是服务器比较常用的功能,防止pin ...
- vue-cli搭建vue项目(单页面应用)
1.全局安装vue-cli 2.创建项目: vue init webpack test test是项目名称,会在当前工作目录下新建一个test文件夹 接下来会手动选择一些配置 除了Setup unit ...
- fancybox图片灯箱功能
fancybox图片灯箱功能 在页面中引入几个文件 <script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery ...
- centos7下查看mysql配置文件适用顺序
mysql --help|grep 'my.cnf' [root@izm5e2q95pbpe1hh0kkwoiz ~]# mysql --help|grep 'my.cnf' order of pre ...
- 消息队列MQ(一)
消息队列 为什么要用消息队列,都有什么优缺点? 要问的是消息队列都有哪些场景,然后项目里具体实现的什么场景,你在这个场景里用的什么消息队列? 期望的回答是,你们公司有个什么业务,这个业务场景有什么技术 ...
- 插入数据失败提示: Setting autocommit to false on JDBC Connection 自动提交失败
来源:https://blog.csdn.net/qq_42799475/article/details/102742109 今天在执行mybstis的测试时,明明已经写好了插入语句但是数据库没有插入 ...
- mutations.js文件书写规范及模板调用此文件书写方法
1)mutations.js代码如下 const mutations={ add(state){ state.count++ }, reduce(state){ state.count-- } } 2 ...
- vuex的state在组件选项data和computed上引用的区别
引用在vue组件的data选项,不因数值被改变而更新引在在vue组件的computed选项,因数值变化而更组件 案例代码如下,调整下引用vue和vuex地址即可展示 <!DOCTYPE html ...
- 解决Intellij Idea下修改jsp页面不自动更新
解决Intellij Idea下修改jsp页面不自动更新 On frame deactivation:被设置成了Do nothing 解决办法:改为Update resources(更新资源)或者Up ...
- 在Oracle中使用sqlload做数据迁移
前提:检查sqlload是否可用,输入sqlldr,提示有版本即可 1.创建测试表(已有则跳过)create table testTable(user varchar2(255),name var ...