python-迭代器与生成器

直接用于for循环的对象,叫做可迭代对象,如列表,字典等。

可以被next()函数调用,并返回下一个值的对象称为迭代器(iterator)。(next()方法在python2.7中使用__next__()方法)。

在调用next()方法时,如果迭代器没有值可以返回,就会引发一个StopIteration异常。

定义迭代器时要有next()方法和__iter__方法:

class Fib(object):
    def __init__(self):
        self.a = 0
        self.b = 1
    def __next__(self):  #注意2和3版本的区别
        self.a , self.b = self.b, self.a + self.b
        return  self.b
    def __iter__(self):
        return  self

然后可以实例化类,直接调用__next__()方法:

fibs = Fib()
print(fibs.__next__())
print(fibs.__next__())
print(fibs.__next__())
print(fibs.__next__())
print(fibs.__next__())

============================
1
2
3
5
8

另外一种迭代方法:

fibs = Fib()
for f in fibs:
    if f >1000:
        print(f)
        break
==========结果==========
1597

一个实现了__iter__()方法的对象师可迭代的,一个实现了next方法的对象则是迭代器。

内建函数iter可以从迭代对象中获得迭代器:

it = iter(["a","b","d","t","l"])

it.__next__()
Out[2]: 'a'

it.__next__()
Out[3]: 'b'

使用list方法可以显式的将迭代器转换为列表

d = iter([4,5,6,7])

ld = list(d)   #将迭代器转换为列表

type(d)
Out[20]: list_iterator

type(ld)
Out[21]: list

ld
Out[22]: [4, 5, 6, 7]


生成器:

包含yield语句的函数称为生成器。

ll = [[1,2],[3,4],[5,6]]
def print_list(list):
    for sublist in list:
        for i in sublist:
            yield i     ###
        print()
for num in print_list(ll):
    print (num, end=" ")

上述函数打印出列表中的每一个数值,注意标记使用的是yield而不是print。

它的行为和普通函数最大的差别在于,它不会像return那样返回值。每次产生一个值,使用yield语句,函数就会被冻结:即函数停在那点等待被重新唤醒。

函数被重新唤醒后就从停止点开始执行。

###python3中的换行打印

https://www.cnblogs.com/hwd9654/p/5707920.html

大家应该知道python中print之后是默认换行的,

那如何我们不想换行,且不想讲输出内容用一个print函数输出时,就需要改变print默认换行的属性,

方法如下:

print('contents', end='!@#$%^&*')

end就表示print将如何结束,默认为end="
"(换行)

栗子:

print("祝各位身体健康")

print("")

 

print("祝各位身体健康", end=' ')

print("")

生成器的与列表推导式:

l = [x if x%3==0 else 0 for x in range(10)]   ##B

l
Out[30]: [0, 0, 0, 3, 0, 0, 6, 0, 0, 9]

l = (x if x%3 == 0 else 0 for x in range(10))   ##A

l.__next__()
Out[33]: 0

l.__next__()
Out[34]: 0

l.__next__()
Out[35]: 0

l.__next__()
Out[36]: 3

l.__next__()
Out[37]: 0

l.__next__()
Out[38]: 0

l.__next__()
Out[39]: 6

把列表生成器中的中括号换成括号就变成了生成器!
生成器是一个包含yield关键字的函数。当它被调用时,在函数体中的代码不会被执行,而会返回一个迭代器。

每次请求一个值,就会执行生成器中的代码,直达遇到一个yield或者return语句,yield意味着应该生成一个值。return语句意味着生成器要停止执行。

““”“生成器由两部分组成:生成器函数和生成器迭代器。生成器函数使用语句定义的,包含yield部分,生成器迭代器是这个函数的返回部分。””

生成器的方法:

  • 生成器可以调用send方法,给yield语句传递一个值。但是需要注意的是,生成器在使用send方法时,生成器必须已经调用,也就是必须已经运行过next()方法。
def repeater(value):   #定义一个生成器
    while True:
        new = (yield value)
        if new is not None:
            value = new
            

r = repeater(42)        #实例一个生成器对象

r.__next__()            #首先调用,执行生成器
Out[42]: 42

r.send("I love LFY")    ##给生成器传入数值
Out[43]: 'I love LFY'

s = repeater(56)        #实例另一个生成器
s.send("wxz")           #然后直接调用send方法,报错!
Traceback (most recent call last):

  File "<ipython-input-46-52ebe91b67e9>", line 1, in <module>
    s.send("wxz")

TypeError: can't send non-None value to a just-started generator   
原文地址:https://www.cnblogs.com/wxzhe/p/8916373.html