Python基础——迭代器/生成器

一:迭代器

迭代:迭代是一种约定,可迭代对象遵循迭代器协议,python内部工具(如for,sum,min,max函数等)

迭代器协议:迭代器协议是指对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个异常(Stoplteration 异常,终止迭代)

迭代器对象:实现了迭代器协议的对象就是迭代器对象(如何实现迭代器协议就是内部有一个__iter__()方法)

如何实现迭代?

>>> a=[1,2,3,4]
>>> a.__iter__()   #获得一个迭代器对象
<list_iterator object at 0x0000000002DD9DD8>   
>>> a=a.__iter__()
>>> a.__next__()
1
>>> next(a)
2
>>> next(a)
3
>>> next(a)
4
>>> next(a)
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    next(a)
StopIteration
#迭代只能依次往下,直到最后一个元素输出,再次调用就会抛出异常

强大的for循环

>>> a=[1,2,3,4]
>>> for i in a:
	print(i)

	
1
2
3
4
#此处的for循环完成了两个功能
1:列表a通过__iter__()方法转换为一个可迭代对象
2:生成迭代器后通过next()或者__next__()方法打印元素

while循环实现迭代

>>> a=[1,2,3,4]
>>> a=a.__iter__()
>>> while True:
	try:
		print(next(a))
	except StopIteration:
		print("迭代终止")
		break

	
1
2
3
4
迭代终止
注意:try和except是异常处理

判断一个对象是否是可迭代对象

#方法1
如果一个对象不支持__iter__方法,那么该对象不是一个可迭代对象
#不是可迭代对象
>>> a=45
>>> "__iter__" in dir(a)
False
#是可迭代对象
>>> a="123"
>>> "__iter__" in dir(a)
True
#方法2
>>> a="123"
>>> from collections import Iterable
>>> isinstance(a,Iterable)
True
>>> a=45
>>> isinstance(a,Iterable)
False

二:生成器

1:生成器表达式

生成器就是一种类型,自动实现了迭代器协议(__iter__)

扫描二维码关注公众号,回复: 2391515 查看本文章

生成器分类:

    1:生成器函数:常规函数定义,但是使用了yield语句而不是return作为函数的返回结果。yield支持多个重复返回,但是return不支持。yield每调用一次就会将函数挂起便于下次从离开位置继续执行

    2:生成器表达式:类似于列表推导式,但是生成器返回按需产生一个结果的对象,而不是一次返回

列表推导式:

    就是基于三元运算而快速在内存中创建一个列表的表达式

==========================================三元运算
比如我们判断一个数字是不是偶数,是偶数输出,不是偶数输出不是偶数
#方法1
num=int(input("输入一个数字: "))
if num%2 == 0:
    print("是偶数")
else:
    print("不是偶数")
#方法2
>>> num=3
>>> "是偶数" if num%2==0 else print("不是偶数")
不是偶数
注:三元运算格式:真的返回值 判断条件 假的返回值
==========================================列表推导式
所谓的列表的推导式就是快速的在内存中生成一个列表
#方法1
>>> a=[]
>>> for i in range(10):
	a.append(i)

	
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#方法2
>>> a=[i for i in range(10)]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
注:列表推导式可以快速的帮我们生成一个列表,虽然速度快,但是如果我们的列表越来越大,那么占用的内存也就越来越大。因此我们可以利用生成器表达式
==========================================生成器表达式
生成器表达式就是一个可迭代的数据类型,本身支持next方法,同时列表推导式用的是[],生成器表达式用的是()
生成一个列表并取值
#方法1
>>> a=[i for i in range(100)]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
#方法2(生成器表达式)
>>> b=(i for i in range(100))
>>> b   #此时b是一个可迭代对象,我们可以通过next方法,也可以用for
<generator object <genexpr> at 0x0000000002E924C0>
>>> next(b)
0
>>> next(b)
1
也可以用for循环
>>> for i in b:
	print(i)
生成器表达式和列表推导式从格式上看没有太大的区别,但是列表解析式是生成一个内存中真实存在的数据占用空间比生成器表达式要大

2:生成器函数

生成器函数就是一个在常规函数中把return换成了yield,如下:

#常规函数
>>> def test():
	return 1
	return 2
	return 3

>>> test()
1
>>> test()
1
>>> test()
1
注意:无论你咋么调用,函数的返回值永远是第一个return生效
#生成器函数
>>> def test():
	yield 1
	yield 2
	yield 3

	
>>> test()
<generator object test at 0x0000000002EB92B0>
>>> a=test()
>>> next(a)
1
>>> next(a)
2
>>> next(a)
3
>>> next(a)
Traceback (most recent call last):
  File "<pyshell#107>", line 1, in <module>
    next(a)
StopIteration

猜你喜欢

转载自blog.csdn.net/spades_linux/article/details/81204245