本节大纲
- 迭代器&生成器
- 装饰器
- 基本装饰器
- 多参数装饰器
- 递归
- 算法基础:二分查找、二维数组转换
- 正则表达式
- 常用模块学习
- 作业:计算器开发
- 实现加减乘除及拓号优先级解析
- 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致
迭代器&生成器
迭代器
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件
特点:
- 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
- 不能随机访问集合中的某个值 ,只能从头到尾依次访问
- 访问到一半时不能往回退
- 便于循环比较大的数据集合,节省内存
生成一个迭代器:
>>> a = iter([1,2,3,4,5]) >>> a <list_iterator object at 0x101402630> >>> a.__next__() >>> a.__next__() >>> a.__next__() >>> a.__next__() >>> a.__next__() >>> a.__next__() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
#!/usr/bin/python3 it = iter(["apple","google","baidu","360"]) print(it) print(type(it)) print(it.__next__()) print(it.__next__()) print(it.__next__()) print(it.__next__())
执行结果:
<list_iterator object at 0x00000000028149B0> <class 'list_iterator'> apple google baidu 360
迭代器对象已经耗尽,对其__next__()方法的任何进一步调用都将再次引发停止迭代
#!/usr/bin/python3 it = iter(["apple","google","baidu","360"]) print(it) print(type(it)) print(it.__next__()) print(it.__next__()) print(it.__next__()) print(it.__next__()) # 迭代器对象已经耗尽,对其__next__()方法的任何进一步调用都将再次引发停止迭代 print(it.__next__())
运行结果:
Traceback (most recent call last): File "D:/py/day001/day1/test.py", line 12, in <module> <list_iterator object at 0x00000000028249B0> print(it.__next__()) StopIteration <class 'list_iterator'> apple google baidu 360
#!/usr/bin/python3 it = iter(["apple","google","baidu","360"]) print(it) print(type(it)) for i in it: print(i)
执行结果:
<list_iterator object at 0x0000000002204C88> <class 'list_iterator'> apple google baidu 360
open文件的迭代
#!/usr/bin/python3 f = open("test.txt","w") f.write("My name is Alice. ") f.write("This is second line. ") f.write("python is good language ") f.write("swift ") f.close() fp = open("test.txt","r") for i in fp: # 迭代 print(i) fp.close()
执行结果:
My name is Alice. This is second line. python is good language swift
反复调用iterator的__next__()方法(或将其传递到内置函数next())返回流中的连续项。当没有更多的数据可用时,就会提出stop迭代异常。此时,迭代器对象已经耗尽,对其__next__()方法的任何进一步调用都将再次引发停止迭代。
在Python中,很多对象都是可以通过for语句来直接遍历的,例如list、string、dict等等,这些对象都可以被称为可迭代对象。至于说哪些对象是可以被迭代访问的,就要了解一下迭代器相关的知识了。
迭代器
迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的__iter__()和next()方法。其中__iter__()方法返回迭代器对象本身;next()(2.x)方法返回容器的下一个元素,在结尾时引发StopIteration异常。
__iter__()和next()(2.x)方法
这两个方法是迭代器最基本的方法,一个用来获得迭代器对象,一个用来获取容器中的下一个元素。
对于可迭代对象,可以使用内建函数iter()来获取它的迭代器对象:
例子中,通过iter()方法获得了list的迭代器对象,然后就可以通过next()(2.x)方法来访问list中的元素了。当容器中没有可访问的元素后,next()方法将会抛出一个StopIteration异常终止迭代器。
其实,当我们使用for语句的时候,for语句就会自动的通过__iter__()方法来获得迭代器对象,并且通过next()方法来获取下一个元素。
生成器generator
定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器
代码:
def cash_out(amount): while amount >0: amount -= 100 yield 100 print("擦,又来取钱了。。。败家子!") ATM = cash_out(500) print("取到钱 %s 万" % ATM.__next__()) print("花掉花掉!") print("取到钱 %s 万" % ATM.__next__()) print("取到钱 %s 万" % ATM.__next__()) print("花掉花掉!") print("取到钱 %s 万" % ATM.__next__()) print("取到钱 %s 万" % ATM.__next__()) print("取到钱 %s 万" % ATM.__next__()) #到这时钱就取没了,再取就报错了 print("取到钱 %s 万" % ATM.__next__())
作用:
这个yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。
另外,还可通过yield实现在单线程的情况下实现并发运算的效果
#!/usr/bin/env python # -*- coding:utf-8 -*- import time def consumer(name): print("%s 准备吃包子啦!" % name) while True: baozi = yield print("包子[%s]来了,被[%s]吃了!" % (baozi, name)) def producer(name): c = consumer('A') c2 = consumer('B') c.__next__() c2.__next__() print("老子开始准备做包子啦!") for i in range(10): time.sleep(1) print("做了2个包子!") c.send("A-%d"%(i)) # 向yield发送 c2.send("B-%d"%(i)) # xiangyield发送 producer("alex")
运行结果:
A 准备吃包子啦! B 准备吃包子啦! 老子开始准备做包子啦! 做了2个包子! 包子[A-0]来了,被[A]吃了! 包子[B-0]来了,被[B]吃了! 做了2个包子! 包子[A-1]来了,被[A]吃了! 包子[B-1]来了,被[B]吃了! 做了2个包子! 包子[A-2]来了,被[A]吃了! 包子[B-2]来了,被[B]吃了! 做了2个包子! 包子[A-3]来了,被[A]吃了! 包子[B-3]来了,被[B]吃了! 做了2个包子! 包子[A-4]来了,被[A]吃了! 包子[B-4]来了,被[B]吃了! 做了2个包子! 包子[A-5]来了,被[A]吃了! 包子[B-5]来了,被[B]吃了! 做了2个包子! 包子[A-6]来了,被[A]吃了! 包子[B-6]来了,被[B]吃了! 做了2个包子! 包子[A-7]来了,被[A]吃了! 包子[B-7]来了,被[B]吃了! 做了2个包子! 包子[A-8]来了,被[A]吃了! 包子[B-8]来了,被[B]吃了! 做了2个包子! 包子[A-9]来了,被[A]吃了! 包子[B-9]来了,被[B]吃了!