每日10行代码105: 编写高质量python代码的方法16:考虑用生成器来改写直接返回列表的函数

如果函数要返回一系列结果,那么最简单的做法就是把这些结果都放在一个列表里返回。例如,我们要查出字符串中每个单词的首字母的位置。下面这段代码是可能的一种实现:

def index_words(text):
	result = []
	if text:
		result.append(0)
	for index,letter in enumerate(text):
		if letter == ' ':
			result.append(index+1)
	return result

address = 'Four score and seven years ago...'
result = index_words(address)
print(result[:3])

输出结果:

[0, 5, 11]

index_words函数有两个问题:一是写得有点拥挤。每次找到新的结果,都要使用append方法。二是函数开始和结束各有一段代码来创建及返回result列表。
这个函数如果用生成器(generator)来写会更好。生成器使用yield表达式。关于yield的用法见我的另一篇博客:
https://blog.csdn.net/weixin_44981444/article/details/108618076
改写后的代码如下:

def index_words_iter(text):
	if text:
		yield 0
	for index,letter in enumerate(text):
		if letter == ' ':
			yield index +1
	
	

address = 'Four score and seven years ago...'
#result = index_words(address)
result = list(index_words_iter(address))
print(result[:3])

用yield的好处在于处理的数据量大时,能防止内存占用过大。
如果处理文件,可以用下面这段:

def index_file(handle):
	offset = 0
	for line in handle:
		if line:
			yield offset
		for letter in line:
			offset += 1
			if letter == ' ':
				yield offset


with open('address.txt','r',encoding='utf-8') as f:
	it  = index_file(f)
	results = islice(it,0,3)
	print(list(results))

定义这种函数时,唯一要注意的是,迭代器是有状态的,只能用一次。
要点:

  • 使用生成器比把收集到的结果放入列表里返回给调用者更加清晰。
  • 由生成器函数所返回的个迭代器,可以把生成器函数体中,传给yield表达式的那些修理,逐次产生出来。
  • 无论输入量有多大,生成器都能产生一系列输出,因为这些输入量和输出量,都不会影响它在执行时所耗的内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值