820 字
4 分钟
Python中的迭代
2020-01-29

概述#

本文记录遇到的部分迭代技巧

迭代工具函数#

其作用是生成可迭代对象

zip(iter1, iter2, …)#

返回一个zip对象,此对象可以生成一个元组,其中的元素分别由iter1、iter2、…等中的元素组成,且该元组的长度由最小的可迭代对象决定

enumerate(iter, start=0)#

生成带索引的枚举对象,默认索引值从0开始,也可指定一个值

代码示例#

nums = [110, 120, 119, 911]
names = ['警察', '医院', '消防']
for thing in zip(nums, names):
print(thing)
> (110, '警察')
> (120, '医院')
> (119, '火警')
for ph, name in zip(nums, names):
print('{0}的电话是:{1}'.format(str(name), str(ph)))
> 警察的电话是:110
> 医院的电话是:120
> 火警的电话是:119
for thing in zip(range(2), nums, names):
print(thing)
> (0, 110, '警察')
> (1, 120, '医院')
d = dict(zip(nums, names)) # 可组成字典
print(d)
> {110:'警察', 120:'医院', 119:'火警'}
for thing in enumerate(names):
print(thing)
> (0, '警察')
> (1, '医院')
> (2, '火警')
for thing in enumerate(names, 100):
print(thing)
> (100, '警察')
> (101, '医院')
> (102, '火警')

yield函数#

一个例子:斐波那契数列#

斐波那契数列(Fibonacci)是这样一个数列,其任意一个数等于该数前两个数的和。

斐波那契数列的简单实现#

一般可用如下代码实现该数列:

def fibonacci(num):
n, a, b = 0, 0, 1
while n < num:
print(b)
a, b = b, a + b
n += 1
fibonacci(5)
> 1
> 1
> 2
> 3
> 5

斐波那契数列实现的进一步讨论#

对于上面的实现函数,其实用性较差,因为这里直接print出数字,其返回值为None。其他函数无法获得该函数生成的数列。

因此,我们可以改进该函数,使其返回一个list:

def fabonacci(num):
n, a, b = 0, 0, 1
result = []
while n < num:
result.append(b)
a, b = b, a + b
n += 1
return result
fab = fabonacci(5)
for n in fab:
print(n)
> 1
> 1
> 2
> 3
> 5

使用yield函数改进#

对于上面的改进版本,当传入的参数num的值很大时,其生成的list也很大,很占内存。要进一步改进,我们可以用迭代器,不用list保存中间结果,而是用iterable对象来迭代。可以通过写一个类,重载该类的__iter__函数和__next__函数来实现。

但这样显然十分繁琐,yield函数就提供了这样一种功能:

def fabonacci(num):
n, a, b = 0, 0, 1
while n < num:
yield b
a, b = b, a + b
n += 1
for n in fabonacci(5):
print(n)
> 1
> 1
> 2
> 3
> 5

仅仅通过把print(b)改成yield b就可以了,十分的简洁、高效。

一个带有yield的函数就是一个generator。这样的函数与普通函数的不同在于,对该函数进行调用时不会执行任何函数代码,直到对其调用next才开始执行(for循环中自动调用next)。

yield的另一个应用场景#

文件读取时,若直接对文件对象使用read()函数,会导致不可预测的内存占用。可以通过设定一定大小的缓冲区来不断读取文件内容:

def read_file(file_path, block_size=1024):
with open(file_path, 'rb') as f:
while True:
block = f.read(block_size)
if block:
yield block
else:
return
Python中的迭代
https://blog.xiaobaizhang.top/posts/python-2-iteration/
作者
张小白
发布于
2020-01-29
许可协议
CC BY-NC-SA 4.0