码迷,mamicode.com
首页 > 其他好文 > 详细

函数进阶

时间:2017-12-25 16:58:24      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:生成器 迭代器 三元表达式

一、迭代器

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!