Python 进阶学习笔记之四:高效迭代器工具

Python 进阶系列笔记文章链接:
Python 进阶学习笔记之一:内置常用类型及方法
Python 进阶学习笔记之二:常用数据类型(上)
Python 进阶学习笔记之三:常用数据类型(下)
Python 进阶学习笔记之四:高效迭代器工具
Python 进阶学习笔记之五:异步 IO
Python 进阶学习笔记之六:多线程编程
Python 进阶学习笔记之七:互联网支持
Python 进阶学习笔记之八:面向对象高级编程
Python 进阶学习笔记之九:IO 编程
Python 进阶学习笔记之十:一般加密支持
Python 进阶学习笔记之十一:日志支持
Python 进阶学习笔记之十二:数据压缩与归档

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 版本新加入的特性。

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 进阶学习笔记之五:异步 IO

你可能感兴趣的:(Python)