Python入门课程3——迭代器和生成器

一、可迭代的

1.什么是“可迭代”的

在Python中,如果一个对象有__iter__( )方法或__getitem__( )方法,则称这个对象是可迭代的(Iterable),其中:
__iter__( )方法的作用是让对象可以用for … in循环遍历;
__getitem__( )方法是让对象可以通过“实例名[index]”的方式访问实例中的元素。
两个条件只要满足一条,就可以说对象是可迭代的。

2.哪些类型的对象是可迭代的

列表、元祖、集合、字符串、字典、文件等

二、迭代器

1.什么是迭代器

迭代器是一个对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。
若变量i定义为一个迭代器对象,接下来每次调用内置函数next(i),都会从当前序列中产生一个后续的元素;如果没有后续元素了,则会抛出一个StopIteration异常。

2.创建迭代器

如果对象obj是可迭代的,那么通过语法iter(obj)可以生成一个迭代器,如:
data = [1,2,4,8]是可迭代的,但它本身不是一个迭代器,调用next(data)是非法的。而通过语法i = iter(data)可以产生一个迭代器,然后可调用next(i)将返回列表中的元素。

>>> data = [1,2,3,4]
>>> next(data)
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    next(data)
TypeError: 'list' object is not an iterator
>>> i = iter(data)				#产生了一个list_iterator类的实例
>>> next(i)
1
>>> next(i)
2
>>> next(i)
3
>>> next(i)
4
>>> next(i)
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    next(i)
StopIteration
>>> 

另外,python中for循环语法使这个过程自动化,为可迭代的对象创造了一个迭代器,然后反复调用下一个元素直至捕获StopIteration异常。

3.迭代器的作用与特征

作用:
迭代器使得对于序列类型的数据结构的遍历行为与被遍历的对象分离。
即我们无需关心该序列的底层结构是什么样子的,只要拿到这个对象,使用迭代器就可以遍历这个对象的内部.

特征

  • 基于同一可迭代对象可创建多个迭代器,各个迭代器通过间接引用回到初始元素集合来维护自身演进的状态
  • 迭代器不存储自己列表的元素,它保存原始列表的当前索引,该索引指向下一个元素。因此,若原始列表的内容在迭代器构造后、但在迭代完成之前被修改,则迭代器将报告原始列表的更新内容。
三、生成器
1.什么是生成器

生成器可以创建一个迭代器

2.创建一个生成器

生成器的语法实现类似函数,但不返回值
例如,找到一个正整数所有的因子,传统函数实现:

def factors(n):
	results = []
	for k in range(1,n+1):
		if n % k == 0:
			result.append(k)
	return results

生成器中实现:

def factors(n):
	for k in range(1,n+1):
		if n % k == 0:
			yield k 

这里使用yield而不是return来表示结果,表明我们正在定义一个生成器而不是传统的函数(这里factors(n)函数也不会显式地输出任何结果)。
每次循环迭代中,python执行程序直到一个yield语句指出下一个值为止(在这一点上,该程序是暂时中断的,只有当另一个值被请求时才恢复)。
如果一个程序员写了一个循环,例如for factor in factors(100)则会创建一个生成器的实例。

另外,生成器可以依赖不同构造中的多个yield语句,由控制的自然流决定生成序列。例如,在上例中,为了显著提高生成器的效率,我们可以进行这样的优化:

def factors(n):
	k = 1
	while k*k <n:
		 if n % k == 0:
			yield k
			yield n//k
		k += 1
	if k * k == n:
		yield k 
3.生成器的优势

python支持产生 隐式迭代序列值函数(类):range(1000000)keys()values()items()不直接返回一个数字列表(没有一个能产生显式的结果列表),而是反馈一个可迭代的range/keys/value对象,无需立刻构建数据结构来储存它所有的值。
从这样的迭代中得到一个显式值的列表:list(range(1000000))list(keys())list(values())list(items())

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值