欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-04 09:02:12
...

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 进阶