Python 进阶学习笔记之四:高效迭代器工具
Python 进阶系列笔记第四篇,前置文章链接:
Python 进阶学习笔记之一:内置常用类型及方法
Python 进阶学习笔记之二:常用数据类型(上)
Python 进阶学习笔记之三:常用数据类型(下)
14. math 模块
和其他语言一样,Python 提供了专门用于计算的的数学模块 math
,实现了常见的幂运算、对数运算、绝对值、取整等运算。还提供了一个单独对复数进行运算的 cmath
模块,对分数进行运算的 fractions
模块,对十进制定点和浮点进行快速运算的 decimal
模块,工具方法,不在累述。
需要注意的其中关于随机数的 random 模块。该模块实现了各种分布的伪随机数生成器。对于整数,从范围中有统一的选择。 对于序列,存在随机元素的统一选择、用于生成列表的随机排列的函数、以及用于随机抽样而无需替换的函数。在实数轴上,有计算均匀、正态(高斯)、对数正态、负指数、伽马和贝塔分布的函数。
最常用函数示例:
import random
random.random() # 返回 [0, 1) 之间的一个小数
random.randint(1, 10) # randint(a, b) 返回 [a, b] 之间的一个整数,a 和 b 都必须指定
random.randrange(1, 10, 2) # randrange(start[, stop][, step]) 返回一个范围内的整数,作用和 randint 类似,但这个函数的 stop 不是强制的,而且还有个步长参数可选
random.choice('abc') # choice(seq) 从一个序列中随机返回一个元素
random.choice(['red', 'blue', 'black'])
random.choices(['a', 'b', 'c'], cum_weights=[10, 15, 20], k=10) # choices(population, weights=None, *, cum_weights=None, k=1) 描述见下面????
l = ['a', 'b', 'c']
random.shuffle(l) # random.shuffle(x[, random]), 将序列 x 随机打乱位置。注意这里的序列必须是可变序列
print(l)
random.sample(l, 2) # sample(x, k), 从序列中随机抽样 k 个元素,对于想对一个不可变序列进行类似 shuffle 乱序的效果,可以这样用 sample(x. len(x))
random.uniform(1, 2) # uniform(a, b), 返回一个 [a, b] 之间的浮点数
choices(population, weights=None, *, cum_weights=None, k=1)
:从序列population中进行K次随机选取,每次选取一个元素(注意会出现同一个元素多次被选中的情况),weights是相对权重值,population中有几个元素就要有相对应的weights值,cum_weights是累加权重值,例如,相对权重〔10, 5, 30,5〕相当于累积权重〔10, 15, 45,50〕。在内部,在进行选择之前,相对权重被转换为累积权重,因此提供累积权重节省了工作。返回一个列表。此函数是从 3.6 版本新加入的特性。
15. itertools — 为高效循环而创建迭代器的函数
itertools 模块标准化了一个快速、高效利用内存的核心工具集,这些工具本身或组合都很有用。它们一起形成了“迭代器代数”,这使得在纯Python中有可能创建简洁又高效的专用工具。
无穷迭代器:
-
count(start[,step])
:累计计数器,可以从 start 一直累计下去 -
cycle(p)
:循环序列 p 中每一个元素 -
repeat(ele [, n])
:重复指定的 ele
import itertools
itertools.count(10) # 输出 10 11 12 13 14
itertools.cycle('ABCD') # 输出 A B C D A B C D ...
itertools.repeat(10, 3) # 输出 10 10 10
根据最短输入序列长度停止的迭代器:
-
chain(p, q)
:相当于把 p 序列和 q 序列连接成一个序列进行处理 -
chain.from_iterable(iterable)
:作用和 chain 一样,区别是参数是一个嵌套序列 -
compress(data, selectors)
:序列元素选择器,根据第二个参数来从第一个参数的序列中筛选出指定元素 -
filterfalse(fun, seq)
:seq中fun(x)为假值的元素 -
groupby(iterable[, key])
:根据key(v)值分组的迭代器 -
islice(seq, [start,] stop [, step])
:seq[start:stop:step]中的元素 -
takewhile(pred, seq)
:seq[0], seq[1], …, 直到pred真值测试失败 -
zip_longest(p, q, ...)
:(p[0], q[0]), (p[1], q[1]), …
chain('ABC', 'DEF') # 输出 A B C D E F
chain.from_iterable(['ABC', 'DEF']) # 输出 A B C D E F
compress('ABCDEF', [1,0,1,0,1,1]) # 输出 A C E F
filterfalse(lambda x: x%2, range(10)) # 输出 0 2 4 6 8
islice('ABCDEFG', 2, None) # 输出C D E F G
takewhile(lambda x: x<5, [1,4,6,4,1]) # 输出 1 4
zip_longest('ABCD', 'xy', fillvalue='-') # 输出 Ax By C- D-
关于 groupby
函数应用示例代码:
from itertools import *
def height_class(h):
if h>180:
return 'tall'
elif h<160:
return 'short'
else:
return 'middle'
friends = [191, 158, 159, 165, 170, 177, 181, 182, 190]
friends = sorted(friends,key = height_class)
for m,n in groupby(friends,key = height_class):
print m
print list(n)
结果:
middle
[165, 170, 177]
short
[158, 159]
tall
[191, 181, 182, 190]
注意,groupby
的功能类似于UNIX中的uniq命令,只对相邻元素尝试进行分组,因此分组之前需要使用sorted()对原循环器的元素,根据key函数进行排序,让同组元素先在位置上靠拢。
上一篇: python进阶(4)
下一篇: 《python进阶编程》学习