Python 用cycle()循环迭代

Python 用cycle()循环迭代cycle()函数重复循环一组值,可用它循环数据集标识符对数据集进行分组。
还可以用它解决简单的fizz-buzz问题,关于该问题的多种解法可参考http://rosettacode.org/wiki/FizzBuzz,基于它的一些有趣变体可参考https://projecteuler.net/problem=1。

可以利用cycle()函数生成一系列TrueFalse值,如下所示:

m3 = (i == 0 for i in cycle(range(3)))
m5 = (i == 0 for i in cycle(range(5)))

返回结果是无限长的布尔值序列:[True, False, False, True, False, False, ...][True, False, False, False, False, True, False, False, False, False, ...]

如果用zip()处理有限个数值序列和上面两个标识序列,可以得到一个三元组序列,第一部分是数值,另外两个是分别代表是否为3的倍数或5的倍数的标识值。注意这里要引入一个有限的可迭代对象来生成目标数据的上限。这样的一系列值及其标识值如下:

multipliers = zip(range(10), m3, m5)

这样就得到了一个生成器对象,可以用list(multipliers)查看其中包含的结果值,如下所示:

[(0, True, True), (1, False, False), (2, False, False), ..., (9, True, False)]

这样就可以拆解三元组了,用一个过滤器选出倍数值,舍弃其他数值:

total = sum(i
    for i, *multipliers in multipliers
    if any(multipliers)
)

for从句将每个元组拆分成两部分:数值i和标识值multipliers,如果标识值含真值,则保留该数值,否则将其舍弃。
该函数在EDA中很有用。

我们经常要处理大型数据集的样本,在最初的清洗和建模阶段,应使用小数据集,然后在更大的数据集上进行测试。使用cycle()函数可以方便从大型数据集中选取记录。给定总体数据大小 N_p 与样本集大小 N_s,可算出循环体的大小。

Python 用cycle()循环迭代

假设用csv模块解析数据,则可以轻松生成子数据集,已知循环体大小cycle_size和两个打开的文件source_filetarget_file,生成子数据集的方法如下:

chooser = (x == 0 for x in cycle(range(cycle_size)))
rdr = csv.reader(source_file)
wtr = csv.writer(target_file)
wtr.writerows(
    row for pick, row in zip(chooser, rdr) if pick
)

首先基于拣选因子cycle_sizecycle()函数生成拣选函数。比如总体数据集大小为10 000 000,拣选数据集大小为1000,即选取了1/10 000的数据。这里我们假设打开数据文件时,这些代码都嵌在with语句中。

接着用基于cycle()函数的生成器表达式和取自CSV读取器的源数据文件过滤数据。由于用chooser()函数和写数据函数都是非严格的,这类处理消耗内存很少。

稍后会介绍如何使用compress()filter()islice()函数实现相同的功能。

用这个方法还能将非标准CSV文件转换为标准CSV文件。只要数据解析器返回格式一致的元组,并通过写文件方法定义好consumer函数,就能用简单的脚本实现许多清洗和过滤操作。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程