python学习日记13

由于大黑山艺术体育学院的原因,今天再鸽一天。
4.4:由于今天codejam的比赛,再鸽一天。
今天开始迭代。

迭代器

魔法方法__iter__返回一个迭代器,它是包含方法__next__的对象,我们可以创建一个表示斐波那契数列的迭代器:

class fib:
    def __init__(self):
        self.a=0
        self.b=1
    def __next__(self):
        self.a,self.b=self.b,self.a+self.b
        return self.a
    def __iter__(self):
        return self
f=fib()
for i in f:
    print(i)
    if i > 1000:
        break

如果没有break,循环会无限进行。
通过可迭代对象调用内置函数iter,可获得一个迭代器:

it=iter([1,2,3])
print(next(it))
print(next(it))

生成器

无论编写什么程序,都可以不使用生成器,但是它强大的功能令人欲罢不能。

nested=[[1,2],[3,4],[5]] #创建一个生成器的参数
def flatten(nested):
    for sublist in nested:
        for element in sublist:
            yield element
#先迭代所有子列表,再迭代每个子列表的元素
#包含yield的函数被成为生成器,它和return的区别是可以生成多个值,每次一个。
#每使用yield生成一个值后,函数都将冻结,即在此停止(可以理解为类似C的static 变量),下次从停止的地方开始执行
print(list(flatten(nested)))
#对生成器进行迭代
for i in flatten(nested):
    print(i)

如果层层嵌套,我们可以递归实现:

nested=[[[1],2],[3,4],[5,[6,[7]]]] 
def flatten(nested):
    try:
        for sublist in nested:
            for element in flatten(sublist):
                yield element
    except TypeError:
        yield nested
print(list(flatten(nested)))

但是上述生成器对字符串对象会引发一些问题,我们可以对其进行改进:

nested=["foo",["bar","java",["c++","C#"]]] 
def flatten(nested):
    #不迭代字符串
    try: nested + ""
    except TypeError :pass
    else:raise TypeError
    try:
        for sublist in nested:
            for element in flatten(sublist):
                yield element
    except TypeError:
        yield nested
print(list(flatten(nested)))

yield意味着应生成一个值,return将停止执行。相比迭代器,生成器的优势是节省内存空间。
生成器可以使用send从外界接收值:

def re(val):
    while 1:
        n=(yield val)#如果不使用返回值可以不括,但建议加括号
        if n is not None: val=n
r=re(55)
print(next(r))
print(r.send("hello"))

生成器还有throw和close方法。throw用于在生成器中引发异常,可以提供一个异常类型、一个可选值和一个traceback对象。close用于停止生成器。

明天将解决一个经典的问题——八皇后问题,属于进阶操作,初步了解可直接忽略。

知识共享许可协议
Text is available under CC BY-NC-SA 4.0 unless otherwise stated.

除非特殊声明,本站所有内容均以 CC BY-NC-SA 4.0协议授权。
上一篇
下一篇