1、迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而来
l=['a','b','c','d'] count=0 while count < len(l): print(l[count]) count+=1
对于列表可以依赖索引取到值,但是数据结构没有索引,比如字典,就需要一种不依赖索引的取值方式,这就需要迭代器了
2、课迭代对象:凡是对象下有__iter__方法,该对象就是可迭代对象(如字符串,列表,字典,集合,元组,文件等)
迭代器对象:内置有__iter__方法和__next__,得到的结果就是迭代器对象(如文件)
可迭代对象执行__iter__方法变成迭代器对象,执行__next__取到里面的值,每次取一个值
dic={'name':'wang','sex':'m',"age":18} dic_iter=dic.__iter__() print(dic_iter.__next__()) #打印取到的name print(dic_iter.__next__()) #打印取到的sex print(dic_iter.__next__()) #打印取到的age print(dic_iter.__next__()) #值取完了,抛出异常StopIteration while True: try: #处理异常的用法 print(next(dic_iter)) except StopIteration: break
我们通过这种方式取到的值,用for循环就可以简单做到,for循环的原理就是把数据变成迭代器对象执行,并加入处理异常
二、三元表达式和列表推导式
1、三元表达式
def my_max(x,y): return x if x > y else y #判断语句在中间,左边写执行语句,右边写else语句 print(my_max(1,3))
2、列表推导式
l=['egg%s' %i for i in range(10)] #列表生成egg0到egg9共十个元素 print(l) l=['egg%s' %i for i in range(10) if i >=5] #加上if判断,只取egg5到egg9共五个元素 print(l)
3、列表推导式的优点
方便,改变了编程习惯,可称之为声明式编程
三、生成器
1、生成器就是迭代器,只要在函数内部出现yield关键字,那么再调用该函数,将不会立即执行函数体代码,会得到一个结果,该结果就是生成器对象
2、yield与return比较
相同点:都有返回值的功能
不同点:return只能返回一次值,而yield可以返回多次值
3、实现range功能
def my_range(start,stop): while True: if start == stop: raise StopIteration yield start #碰到yield,程序会暂停,执行next会得到返回值1,接着往下执行start变成2,接着循环,最后取到的值就是1和2 start+=1 g=my_range(1,3) for i in my_range(1,3): print(i)
4、实现 python3 tail.py -f access.log | grep 'error'功能
import time def tail(filepath): with open(filepath, 'r') as f: f.seek(0, 2) while True: line = f.readline() if line: #有新的内容,用yield返回,因为yield可以多次返回值 yield line else: time.sleep(0.2) def grep(pattern,lines): for line in lines: #先查看所有的行,然后找出现error模式的行 if pattern in line: print(line,end='') grep('error',tail('access.log'))
四、面向过程的编程
1、编程思想:核心是过程,即解决问题的步骤,先做什么再做什么,是一种机械式的编程思想
2、优缺点
优点:复杂问题流程化,进而简单化
缺点:可扩展性差
五、递归和二分法
1、递归调用:递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身
递归分为两个阶段:递推,回溯
2、递归的使用:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出
补充:在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
def salary(n): if n == 1: return 100 return salary(n-1)+300 print(salary(5))
分析:需要salary(5)的值,返回salary(4)+300,接着取salary(4)的值,一直递推,直到遇到结束条件salary(1)返回值为100,然后回溯,得到salary(5)的值1300
3、二分法
将整个列表切分为两份,取中间值和要找的数据作比较,判断在哪一部分,然后再在那一部分切分,再次取值判断,直到最终找到需要的数据
想从一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率太低,用二分法(算法的一种,算法是解决问题的方法)可以极大低缩小问题规模
六、匿名函数
1、lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字
2、有名函数与匿名函数的对比
有名函数:循环使用,保存了名字,通过名字就可以重复引用函数功能
匿名函数:一次性使用,随时随时定义
应用:max,min,sorted,map,reduce,filter
salaries={ 'wang':3000, 'li':100000, 'tom':10000, 'jim':2000 } print(max(salaries)) #取到的结果是wang print(min(salaries)) #取到的结果是jim 可以看到结果不是我们想要的,因为max,min函数只是把字典的key做比较得到的最大值,最小值,而我们要的是后面的工资的最大值和最小值 print(max(salaries.values())) #取到的结果是100000 print(min(salaries.values())) #取到的结果是2000
3、通常我们都是想取出,工资最高的那个人名,即比较的是salaries的值,得到的是键
print(max(salaries,key=lambda k:salaries[k])) #取到的结果是li,是我们需要的值 print(min(salaries,key=lambda k:salaries[k])) #取到的结果是jim,是我们需要的值
原文地址:http://blog.51cto.com/qidian510/2054419