几个 Python“小伎俩” | 内附代码
来源 | NewBeeNLP(ID:gh_627b00c8dbd0)
责编 | 夕颜
写在前面
今天,我们一起回顾下Python Cookbook,全书是以问答对的形式展开,这是我很久之前看的笔记。Cookbook不算是入门书,更像是一本工具书,既然有基础了那就没必要一个个点去看,建议是需要用到那部分就把那块的知识点技巧翻一遍。下面大噶自己查漏补缺吧!
数据结构与算法
从任意长度的可迭代对象中分解元素
*表达式可以用来将一个含有N个元素的数据结构类型分解成所需的几部分。
1first, *middle, last = grades
例如grades保存了100个成绩数据而我们只关心首末两个成绩,就可以把中间的所有成绩保存到一个列表里面,如下:
保存最后N个元素
collection.deque(maxlen=N)创建了一个固定长度的队列,当有新记录加入而队列已满时会自动移除最老的那条记录。
若不指定队列的大小,也就得到了一个无界限的队列;
deque支持从队列两端添加或弹出元素
1from collection import deque
2q = deque()
3q.append(1)
4q.append(2)
5q.append(3)
6q.appendleft(4)
7q.pop()
8q.popleft()
找到最大或最小的N个元素
heapq模块中有两个函数:nlargest()和nsmallest()
1import heapq
2
3nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
4print(heapq.nlargest(3, nums))
5out: [42, 37, 23]
6print(heapq.nsmallest(3,nums))
7out: [-4, 1, 2]
这两个函数还可以接受一个参数key
1In [1]: portfolio = [2 ...: {'name': 'IBM', 'shares': 100, 'price': 91.1},3 ...: {'name': 'AAPL', 'shares': 50, 'price': 543.22},4 ...: {'name': 'FB', 'shares': 200, 'price': 21.09},5 ...: {'name': 'HPQ', 'shares': 35, 'price': 31.75},6 ...: {'name': 'YHOO', 'shares': 45, 'price': 16.35},7 ...: {'name': 'ACME', 'shares': 75, 'price': 115.65}8 ...: ]9
10cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
11cheap
12out:
13[{'name': 'YHOO', 'price': 16.35, 'shares': 45},
14 {'name': 'FB', 'price': 21.09, 'shares': 200},
15 {'name': 'HPQ', 'price': 31.75, 'shares': 35}]
让字典保持有序
collection模块的OrderedDict会按照元素初始添加的顺序进行操作;
其内部维护了一个双向链表,它会根据元素加入的顺序来排列键的位置。因此OrderedDict的大小是普通字典的2倍多。
字典的计算问题
利用zip()将字典的键与值反转
找出序列中出现次数最多的元素
collection模块的Counter类
并且Counter类有一个非常方便的most_common(n)方法可以直接得到出现次数最多的前几位
1from collections import Counter
2words = [一系列单词组成的列表]
3word_counts = Counter(words)
4top_3 = word_counts.most_common(3)
通过公共键对字典列表排序
operator模块的itermgetter函数
1from operator import itemgetter23In [26]: rows = [4 ...: {'fname': 'Brian', 'lname': 'Jones', 'uid':1003},5 ...: {'fname': 'David', 'lname': 'Beazley', 'uid':1002},6 ...: {'fname': 'John', 'lname': 'Cleese', 'uid':1001},7 ...: {'fname': 'Big', 'lname': 'Jones', 'uid':1004}8 ...: ]9
10itemgetter('fname')
11Out[31]: <operator.itemgetter at 0x7f01606657d0>
12
13rows_by_frame = sorted(rows, key=itemgetter('fname'))
14Out[30]:
15[{'fname': 'Big', 'lname': 'Jones', 'uid': 1004},
16 {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
17 {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
18 {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
itermgetter()函数还可以接受多个键
1rows_by_frame = sorted(rows, key=itemgetter('fname','lname'))
数字、日期和时间
对数值进行取整
使用内建的round(value, ndigits)函数
1>>> round(1.23, 1)
21.2
3>>> round(1.27, 1)
41.3
5>>> round(162773, -1)
6162770
当某个值恰好等于两个整数间的一半时,取整操作会去到离该值最近的那个偶数上。如1.5和2.5都会取整到2
round()中的ndigits可以是负数,在这种情况下会相应地取整到十位、百位。。。
对数值做格式化输出
使用内建的format()函数
1>>>x = 123.456
2>>>format(x, '0.2f')
3123.46
二进制、八进制和十六进制转换
要将一个整数转换为二进制,使用bin()
要将一个整数转换为八进制,使用oct()
要将一个整数转换为十六进制,使用hex()
随机选择
random.choice()可以从序列中随机挑选出元素
1>>>import random
2>>>values = [1,2,3,4,5,6]
3>>>random.choice(values)
44
5>>>random.choice(values)
62
random.shuffle()可以在序列中原地打乱元素的顺序
1>>>random.shuffle(values)
2>>>values
3[2,4,3,1,6,5]random.sample()可以取样出N个元素
random.sample()可以取样出N个元素
1>>>random.sample(values, 2)
2[6, 2]
时间换算
datatime模块可以用来完成不同时间单位间的换算。例如要表示一个时间间隔,可以创建一个timedelta实例
1from datetime import timedelta23In [33]: a = timedelta(days=2, hours=6)4In [34]: b = timedelta(hours=4.5)5In [35]: c = a + b6In [36]: c.days7Out[36]: 28In [37]: c.seconds9Out[37]: 37800
10In [38]: c.seconds/3600
11Out[38]: 10.5
12In [39]: c.total_seconds() / 3600
13Out[39]: 58.5
迭代器和生成器
手动访问迭代器中的元素
1with open('/etc/passwd') as f:
2 try:
3 while True:
4 line = next(f)
5 print(line, end='')
6 except StopIteration:
7 pass
委托迭代
对自定义的容器对象,其内部持有一个列表丶元组或其他的可迭代对象,我们想让自己的新容器能够完成迭代操作。一般来说,我们所要做的就是定义一个__iter__()方法,将迭代请求委托到对象内部持有的容器上。
1class Node:
2 def __init__(self, value):
3 Self._value = vaule
4 self._children = []
5 def __repr__(self):
6 return 'Node({!r})'.format(self._value)
7 def __iter__(self):
8 return iter(self._children)
在这个例子中,iter()方法将迭代请求转发给对象内部持有的_children属性上。
用生成器创建新的迭代模式
函数中只要出现了yield语句就会将其转变成一个生成器
1def frange(start, stop, increment):
2 x = start
3 while x < stop:
4 yield x
5 x += increment
注意生成器只在响应迭代操作时才运行
对迭代器做切片操作
itertool.islice() 可以对迭代器和生成器做切片操作
1In [3]: def count(n):2 ...: while True:3 ...: yield n4 ...: n += 15 ...:6In [5]: c = count(0)7In [6]: c8Out[6]: <generator object count at 0x7f92899b3c80>9----> 1 c[0]
10TypeError: 'generator' object has no attribute '__getitem__'
11
12import itertools
13In [10]: for x in itertools.islice(c, 10, 20):
14 ...: print(x)
1510
1611
1712
1813
1914
2015
2116
2217
2318
2419
跳过可迭代对象中的前一部分元素
itertools.dropwhile() 函数会 丢弃掉序列中的前面几个元素
例如,我们需要读取一个文件,文件的开头有一系列注释行并不是我们想要的
1from itertools import dropwhile
2with open('/etc/passwd') as f:
3 for line in dropwhile(lambda line: line,startwith('#'), f):
4 print(line, end='')
迭代所有可能的组合
我们想对一些列元素的所有可能组合进行迭代
itrtools.permutations()函数接受一个元素集合,将其中所有元素重排列为所有可能的情况,并以元组的形式返回。
1In [11]: from itertools import permutations2In [12]: items = ['a', 'b', 'c']3In [13]: for p in permutations(items):4 ...: print(p)5 ...:6('a', 'b', 'c')7('a', 'c', 'b')8('b', 'a', 'c')9('b', 'c', 'a')
10('c', 'a', 'b')
11('c', 'b', 'a')
#如果想得到较短的所有全排列,可以指定长度
In [14]: for p in permutations(items, 2):...: print(p)
('a', 'b')
('a', 'c')
('b', 'a')
('b', 'c')
('c', 'a')
('c', 'b')
itertools.combinations 不考虑元素间的实际顺序,即('a', 'b')和('b', 'a')被认为是相同的组合形式。
若想解除这一限制,可用combinations_with_replacement。
同时迭代多个序列
zip()函数可以用来迭代多个序列中的元素
1>>>xvalues = [1,5,4,2,10,7]2>>> yvalues = [101,78,37,15,62,99]3>>> for x, y in zip(xvalues, yvalues):4... print(x, y)5...61 10175 7884 3792 15
1010 62
117 99
在不同的容器中进行迭代
我们需要对许多对象执行相同的操作,但是这些对象包含在不同的容器内,而我们希望可以避免写出嵌套的循环处理,保持代码的可读性。使用itertools.chain()方法可以用来简化这个任务。
1from itertools import chain23In [18]: a = [1, 2, 3, 4]4In [19]: b = ['x', 'y', 'z']5In [20]: for x in chain(a, b):6 ...: print (x)7 ...:8192
103
114
12x
13y
14z
合并多个有序序列,再对整个有序序列进行迭代
heapq.merge()函数
1>>>import heapq2>>>a = [1,4,7,10]3>>>b = [2,5,6,11]4>>>for c in heapq.merge(a,b):5... print(c)6...718294
105
116
127
1310
1411
文件和IO
将输出重定向到文件中
只需要在print()函数加上file关键字参数即可
1with open('somefile.txt', 'rt') as f:
2 print('Hello World!', file=f)
以不同的分隔符或行结尾符完成打印
1>>>print('GKY',1995,5,18, sep='-',end='!!\n')
GKY-1995-5-18!!
在字符串上执行IO操作
使用io.StringIO()和io.ByteIO()来创建类似于文件的对象,这些对象可操作字符串数据。
读写压缩的数据文件
gzip和bz2模块可以实现
1import gzip2with open('somefile.gz', 'rt') as f:3 text = f.read()45import bz26with open('somefile.bz2', 'rt') as f:7 text = f.read()89import gzip
10with open('somefile.gz', 'wt') as f:
11 f.write(text)
12
13import bz2
14with open('somefile.bz', 'wt') as f:
15 f.write(text)
将二进制数据读到可变缓冲区中
我们想将二进制数据直接读取到一个可变缓冲区中,中间不经过任何拷贝环节。例如我们想原地修改数据再将它写回到文件中去。
1import os.path2def read_into_buffer(filename):3 buf = bytearray(os.path.getsize(filename))4 with open(filename, 'rb') as f:5 f.readinto(buf)6 return buf78with open('sample.bin', 'wb') as f:9 f.write(b'hello world')
10
11buf = read_into_buffer('sample.bin')
12In [16]: buf
13Out[16]: bytearray(b'hello world')
序列化Python对象
我们需要将Python对象序列化为字节流,这样就可以将其保存到文件中、存储到数据库中或者通过网络连接进行传输。
序列化数据最常见的做法就是使用pickle模块。
1import pickle
2data = ... #some python object
3f = open('somefile', 'wb')
4pickle.dump(data,f)
要将对象转存为字符串,可以使用
1import pickle
2data = ... #some python object
3f = open('somefile', 'wb')
4pickle.dumps(data,f)
如果要从字节流中重新创建出对象,可以使用pickle.load()或者pickle.loads()
数据编码与处理
读写JSON数据
主要使用JSON模块
两个主要的函数为json.dumps()和json.loads()
如果是文件而不是字符串的话使用json.dump()和json.load()
解析简单的XML文档
xml.etree.ElementTree可以从简单的XML文档中提取数据
1from urllib.request import urlopen2from xml.etree.ElementTree import parse34u = urlopen('http://planet.python.org/rss20.xml')5doc = parse(u)6In [24]: for item in doc.iterfind('channel/item'):7 ....: title = item.findtext('title')8 ....: date = item.findtext('pubDate')9 ....: link = item.findtext('link')
10 ....: print (title)
11 ....: print(date)
12 ....: print(link)
13 ....: print()
14 ....:
【End】
技术战“疫”,贾扬清、李飞飞要给程序员直播讲AI技术!
2月18日、2月20日,阿里云CIO学院攻“疫”技术课程正式开启。您将获得与达摩院数据库首席科学家 、阿里巴巴集团副总裁、ACM 杰出科学家李飞飞,Caffe之父、ONNX创始人、阿里巴巴集团副总裁贾扬清,阿里巴巴集团副总裁、阿里 CIO 学院院长胡臣杰等顶级技术专家直播互动的机会。
推荐阅读
☞工信部:短信可为 16 亿用户提供行程证明;OPPO 回应造芯计划;Windows Terminal 0.9 发布| 极客头条
☞ 抗疫新举措,本周内你也能用上健康码!
☞几行代码构建全功能的对象检测模型,他是如何做到的?
☞疫情之下,哪些行业正在逆势爆发?
☞早期文献中的关系抽取论文整理,赶紧 Mark 起来!
☞一文读懂拜占庭将军问题
你点的每一个在看,我认真当成了喜欢
猛戳“阅读原文”,立即加入!
几个 Python“小伎俩” | 内附代码相关推荐
- Python实现智力问答小游戏 内附代码
本篇文章将使用Python代码语言简单编写一个轻松益智的小游戏,效果如下所示: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QG0hhvFR-163618697978 ...
- 我用Python爬取了难下载的电子教材(内附代码)
我用Python爬取了难下载的电子教材(内附代码) 第一次在CSDN上面分享经历,有点激动.本大二狗最近这段时间去不了学校又想看教材,不巧学习通上面的部分内容老师设置了不可下载啊.好在最近学习了一点P ...
- python常用代码入门-入门十大Python机器学习算法(附代码)
入门十大Python机器学习算法(附代码) 今天,给大家推荐最常用的10种机器学习算法,它们几乎可以用在所有的数据问题上: 1.线性回归 线性回归通常用于根据连续变量估计实际数值(房价.呼叫次数.总销 ...
- Python小数据池,代码块
今日内容一些小的干货 一. id is == 二. 代码块 三. 小数据池 四. 总结 python小数据池,代码块的最详细.深入剖析 一. id is == 二. 代码块 三. 小数据池 四. 总结 ...
- Appgamekit制作消消乐小游戏(附代码)# 1
Appgamekit制作消消乐小游戏(附代码)# 1 其实作者我也是刚刚才接触的Appgamekit,而且以前我是学C/C++的,所以我学的东西拿来这里就只有代码的结构思路会清晰一点了.(但是思路其实 ...
- python小游戏-16行代码实现3D撞球小游戏!-源码下载
python小游戏-16行代码实现3D撞球小游戏!-源码下载 所属网站分类: 资源下载 > python小游戏 作者:搞笑 链接: http://www.pythonheidong.com/bl ...
- 混合整数规划MIP/线性规划LP+python(cplex库)实现 附代码
文章目录 相关知识点 LP线性规划问题 MIP混合整数规划 MIP的Python实现(docplex库) MIP的Python实现(ortool库) 喜欢的话请关注我们的微信公众号~<你好世界炼 ...
- 混合整数规划MIP/线性规划LP+python(ortool库)实现 附代码
文章目录 相关知识点 LP线性规划问题 MIP混合整数规划 MIP的Python实现(Ortool库) assert MIP的Python实现(docplex库) 喜欢的话请关注我们的微信公众号~&l ...
- VAE逻辑整理及VAE在异常检测中的小实验(附代码)
VAE逻辑整理及VAE在异常检测中的小实验(附代码) Variance和control variate 两种常见的分类器 相应代码 Minst数据集的训练和重构 KDD99数据 本文主要讲解一下整个 ...
最新文章
- 基于Redis的单点登录
- cuda nvcc版本不一致_入坑第一步:Win10安装cuda+cuDNN+TensorFlow-GPU走过的那些路
- java中的枚举类_java中的枚举类型
- Spring Schedule定时关单快速入门
- mysql 关闭锁_mysql数据库取消锁
- [css] css的加载会阻塞DOM树解析和渲染吗?为什么
- 让8只数码管初始显示零,每隔大约1s加一显示,到数码管显示9后,再从一开始显示
- Android 系统(138 )---Mtk平台 Android 打包解包*.img ,修改system.img 参数
- 删库只能跑路?程序员自救宝典!| 原力计划
- 如何使用BootStrapDialog实现数据的添加与删除?
- java之beanutils技术
- 热门好用的邮编查询API
- 学习机器视觉需要掌握哪些知识?【转】
- nanomsg笔记--通信协议与传输协议
- Webpack Chunk 分包规则
- 格斗类游戏的键盘处理
- 6个不为人知的高质量APP推荐:知乎3万人点赞,2万人收藏!
- 服务器中搭建OA系统,云服务器搭建oa系统
- 使用Motrix解决浏览器下载速度慢的问题
- 物联通信安全需求如何实现