Python基础_生成器与迭代器

列表的定义

方法一:
a = [1,2,3,4,5,6,7,8,9] 
print(a)
方法二:
a = [x for x in range(10)]

如果要将列表中的数都乘以2:

方法一:
a = []
for i in range(10):
    a.append(i*2)
方法二:
a = [x*2 for x in range(10)]

可以看出,两个定义列表与改变列表中的数,方法二都比方法一更加简单,而方法二就称为列表生成式

生成器

列表的元素可以按照某种算法推算出来,并且在执行循环的时候不断推算出后续的元素,不必实现生成一个完整的列表,一边循环,一边计算,这种机制就称为生成器(generator)。

为什么要使用生成器?

如果新建一个含有1000万个元素的列表,势必会占很大的内存空间,并且只需要前几条元素,又会造成空间浪费,使用生成器动态生成元素就可以节省很大的内存。

创建生成器

//列表生成式
a = [i*2 for i in range(10)]  #[0,2,4,6,8,10,12,14,16,18]
//生成器
a = (i*2 for i in range(10))  #generator object <genexpr> at 0x0000017E4C38A6D8>

列表生成式和生成器表面区别:

1.列表生成式定义用[ ],生成器定义用()。

2.列表生成式结果为列表具体元素,生成器的结果为generator object <genexpr> at 0x0000017E4C38A6D8>。

而打印生成器的结果就需要用到 __ next__()方法

a = (i*2 for i in range(10))
print(a.__next__())    #0
print(a.__next__())    #2
print(a.__next__())    #4
print(a.__next__())    #6
print(a.__next__())    #8
当元素输出完毕后会报错:print(a.__next__())    StopIteration

利用for循环输出:
a = (i*2 for i in range(10))
for i in a:
    print(i)

用函数定义生成器

//用函数实现输出累加的过程
def sum(num):
    a,sum = 0,0
    while num >= a:
        sum = sum + a
        a = a + 1
        print(sum)
    return "done"
sum(10)

//用生成器实现输出累加的过程
def sum(num):
    a,sum = 0,0
    while num >= a:
        sum = sum + a
        a = a + 1
        yield sum
    return "done"
print(sum(10))
结果:<generator object sum at 0x000001B3ED38B408>
f = sum(10)
print(f.__next__())
print(f.__next__())
结果:0 1

当print(sum)改为yield sum后,该累加函数就已经变成了一个生成器,函数遇到return才会返回值,而生成器执行时遇到yield就会返回到__next__()处,当再次调用__next__()方法时,会回到上一次退出的yield处继续执行。

生成器send()方法

def test():
    print("开始")
    while True:
        value = yield
        print("这是一个%s"%value)

f = test()
f.__next__()
f.send("生成器")
结果:开始
······这是一个生成器

send()是生成器很重要的一个方法,可以利用send方法向生成器内部传递参数,如上例将“生成器”传递给value

为什么在f = test()后要先加一句f.__next__()?

当执行完语句f = test()后,生成器并不会继续往下执行,它会停留在def test(),只有调用f.__next__()后才会继续往下执行,寻找yield,找到yield后才停止,上例中输出一个开始就很好的说明了这个问题。

迭代对象

可以直接用于for循环的类型称之可迭代对象,例如:列表 元组 集合 字典 生成器

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

from collections import Iterable
isinstance([],Iterable)

迭代器

可以被next()函数调用并不断返回下一个值的对象成为迭代器:Iterator

判断一个对象是否是迭代器:

from collections import Iterator
isinstance((x for x in range(10)), Iterator)

 注意:迭代对象不一定是迭代器

列表字典元组Iterable(迭代对象)变成Iterator(迭代器)可以使用iter()函数:

isinstance(iter([]), Iterator)

猜你喜欢

转载自blog.csdn.net/w819104246/article/details/92631296