一、迭代器

1、迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而来

l=['a','b','c','d']count=0while 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__())               #打印取到的nameprint(dic_iter.__next__())               #打印取到的sexprint(dic_iter.__next__())             #打印取到的ageprint(dic_iter.__next__())             #值取完了,抛出异常StopIterationwhile 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+=1g=my_range(1,3)for i in my_range(1,3):    print(i)

4、实现 python3 tail.py -f access.log | grep 'error'功能

import timedef 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)+300print(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))      #取到的结果是wangprint(min(salaries))      #取到的结果是jim可以看到结果不是我们想要的,因为max,min函数只是把字典的key做比较得到的最大值,最小值,而我们要的是后面的工资的最大值和最小值print(max(salaries.values()))    #取到的结果是100000print(min(salaries.values()))    #取到的结果是2000

3、用zip函数解决(zip函数也叫拉链函数)

a=[1,2,3]b=['q','w','s','e']res=zip(a,b)print(list(res))     #得到的结果是[(1, 'q'), (2, 'w'), (3, 's')],就是把两个列表的元素一一对应,多余的元素不管解决上面的问题:把上面字典的键值对调res=zip(salaries.values(),salaries.keys())print(max(res))                             #得到最大工资的键值对组成的元组(100000, 'li')print(max(res)[1])                           #得到工资高的人li

4、通常我们都是想取出,工资最高的那个人名,即比较的是salaries的值,得到的是键

print(max(salaries,key=lambda k:salaries[k]))      #取到的结果是li,是我们需要的值print(min(salaries,key=lambda k:salaries[k]))      #取到的结果是jim,是我们需要的值

5、按照薪资高低进行排序sorted

res=sorted(salaries,key=lambda k:salaries[k])print(res)                     #得到从低到高的顺序['jim', 'wang', 'tom', 'li'] 如果要求反向排序,即实现从高到低排序print(sorted(salaries,key=lambda k:salaries[k],reverse=True))     #得到从高到低的顺序['li', 'tom', 'wang', 'jim']

6、map函数,做映射

l=['wang','li']map(lambda x:x+'_man',l)                   #对列表的每个元素后面添加_man字符串print(list(map(lambda x:x+'_man',l)))           #得到结果['wang_man', 'li_man']

7、reduce函数 :实现合并

from functools import reduce        #这个函数需要导入模块print(reduce(lambda x,y:x+y,range(1,101)))     #1到100的和,结果是5050

8、filter函数,实现过滤

l=['wang_man','li_man','tom']res=filter(lambda name:name.endswith('man'),l)   #元素里面以字符串man结尾的print(list(res))             #过滤的结果['wang_man', 'li_man']

七、内置函数,要看到结果用print打印出来即可

1、数学运算

abs(-5)                          # 取绝对值,也就是5round(2.6)                       # 四舍五入取整,也就是3.0pow(2, 3)                        # 相当于2**3,如果是pow(2, 3, 5),相当于2**3 % 5 结果是3divmod(9,2)                      # 返回除法结果和余数,适用于判断数据需要分多少页max([1,5,2,-2])                    # 求最大值min([9,2,1,3])                    # 求最小值sum([1,2,3])                     # 求和

2、类型转换

ord("A")  # "A"字符对应的数值chr(65)  # 数值65对应的字符bool(0)  # 转换为相应的真假值,在Python中,0相当于False,下列对象都相当于False: [], (), {}, 0, None, 0.0, ''bin(56)  # 返回一个字符串,表示56的二进制数hex(56)  # 返回一个字符串,表示56的十六进制数oct(56)  # 返回一个字符串,表示56的八进制数list((1, 2, 3))   # 转换为列表[1, 2, 3]tuple([2, 3, 4])  # 转换为(2, 3, 4)dict(a=1, b="hello", c=[1, 2, 3])  # 构建字典{'a': 1, 'b': 'hello', 'c': [1, 2, 3]}

3、序列操作

all([True, 1, "hello!"])      # 所有的元素都相当于True值时返回Trueany(["", 0, False, [], None])  # 有任意一个元素相当于True值时返回Truesorted([1, 5, 3])          # 序列进行排序,也就是[1,3,5]reversed([1, 5, 3])         # 序列反转,也就是[3,5,1]

4、其他常见内置函数

type([1,2,3])            #[1,2,3]是list类型len([1,2,3])             #[1,2,3]的长度是3range(1,5,2)             #快速生成序列,1到9,步长为2,结果是1和3enumerate函数:l=['a','b']for i in enumerate(l):    print(i)           #得到结果是(0, 'a') (1, 'b'),这样可以得到元素对应的索引eval函数和exec函数s='1+2+3'print(eval(s))      #eval用来执行表达式,并返回表达式执行的结果,结果是6print(exec(s))      #exec用来执行语句,不会返回任何值print(eval('1+2+x',{'x':3},{'x':30}))       #返回33print(exec('1+2+x',{'x':3},{'x':30}))      #返回Noneprint(eval('for i in range(10):print(i)'))   #语法错误,eval不能执行表达式print(exec('for i in range(10):print(i)'))   #执行语句,得到语句的结果