python小结(二) 函数(小白总结)&生成器&迭代器(定义)
【def】
定义一个函数 f() 调用这个函数 f 只是相当于调用一个函数对象,返回的是一个函数的内存地址,要搞清楚这一点,这样会对以后高阶函数的理解有帮助
def f(): print "ok" f() 运行结果: ok
【参数】
给函数添加参数:1。 普通的参数 2。默认参数 3.不定长参数
【默认参数】
一般默认参数放在最后
def f(name,age=12): print "I am {name} I am {age}".format(name=name,age=age) f("Tom") 运行结果: I am Tom I am 12
【不定长参数】
1 无命名的不定长参数
def add(*args): #不定参数无命名 sum = 0 for i in args: sum+=i return sum sum =add(1,2,3,4,5) print sum 运行结果: 15 #当你添加的是列表时 def a(*args): print args a(*[1,2,3,4]) #####单个添加到元组#### 运行结果: (1, 2, 3, 4)
2。有命名的不定长参数
def login(**kwargs): #有命名 print kwargs for i in kwargs: print i login(name="Tom",age=19,sex="man") 运行结果: {'age': 19, 'name': 'Tom', 'sex': 'man'} age name sex def b(**kwargs): print kwargs b(**{"name":"aa"}) ######键值对方式添加到字典#### 运行结果: {'name': 'aa'
【return】
结束函数,返回某个对象
如果未在函数中指定return,那这个函数的返回值为None
可以返回多个对象 ,默认放到一个元组中
【作用域】
总共可以划分为Legb
built_in (系统定义) global(全局变量) enclosing(嵌套变量) local(局部变量)
count = 10 # count =["1","2"] def out(): global count ##申明全局变量 count+=1 ##当全局变量不可变时,局部变量不可修改,除非申明全局变量 # count.append("3") ##当是可变的类型时,内部可以对他进行修改 print count out() 运行结果: 11
【高阶函数】
高阶函数是至少满足下列一个条件的函数:
1.接受一个或多个函数作为输入
2.输出一个函数
def f(n): return n*n def foo(a,b,fn): return fn(a)+fn(b) ####fn()就是运行这个f()函数###### print foo(1,2,f) ######f就是一个函数的内存地址###### def f(): return 8 def fun(): return f ter=fun() #####只是得到f函数的内存地址###### print ter print ter() ####只要加上括号就代表运行这个函数,所以就是运行f()这个函数 运行结果: 5 <function f at 0x00000000026CEBA8> 8
【递归函数】
定义:简单的可以概括为:调用自己的函数+结束条件
######递归求阶乘##### def f(n): if n==1: return 1 return n*f(n-1) #####调用自己,结束条件 print f(7) print reduce(lambda a,b:a*b ,range(1,8)) #之后会讲到这几个重要的内置函数,现在只是了解会有更简单的方法来实现递归 运行结果: 5040 5040
【斐波那契数列】
可以很好地解释递归函数,好好理解一下斐波那契数列,后边会以这个数列来讲解生成器
def f(n): if n<=2: return n return f(n-1)+f(n-2) print f(5) 运行结果: 8
【内置函数】
py2内置函数:https://docs.python.org/3.5/library/functions.html#repr
几个重要的内置函数:
1。filetr(function,squence) 对sequence中的item依次执行function(item),将执行结果为True的item做成一个filter object的迭代器返回。可以看作是过滤函数。
2。map(function,squence) 对sequence中的item依次执行function(item),将执行结果组成一个map object迭代器返回.map也支持多个sequence,这就要求function也支持相应数量的参数输入:
3。reduce(function,squence) 对sequence中的item顺序迭代调用function,如果有starting_value,还可以作为初始值调用.
4.。lambda(function,squence) 匿名函数的命名规则,用lamdba 关键字标识,冒号(:)左侧表示函数接收的参数(a,b) ,冒号(:)右侧表示函数的返回值(a+b)。因为lamdba在创建时不需要命名,所以,叫匿名函数
#filter str = ["a","b","c","d","e"] def func(s): #print s if s !="a": return s let = filter(func,str) print list(let) #map str = [ 'a', 'b'] def fun2(s): return s + "alvin" ret = map(fun2, str) print(ret) # map object的迭代器 print(list(ret)) # ['aalvin', 'balvin', 'calvin', 'dalvin'] #reduce from functools import reduce def add1(x, y): return x + y print (reduce(add1, range(1, 101))) ## 5050 (注:1+2+...+100) print (reduce(add1, range(1, 101), 20)) ## 5070 (注:1+2+...+100+20) #lambda #普通函数 def add(a, b): return a + b print add(2, 3) # 匿名函数 add = lambda a, b: a + b print add(2, 3) 运行结果: ['b', 'c', 'd', 'e'] ['aalvin', 'balvin'] ['aalvin', 'balvin'] 5070 5
【装饰器函数】
1.闭包的概念:a)有一个内部函数 b)引用一个外部变量
2.装饰器的作用:遵守开放,闭合的原则,在不修改原来的代码的基础上添加要求,调用的时候重新赋值相当于调用原来的函数, 不会影响其他对该函数的调用
下面是两个例子来帮助理解装饰器,装饰器再python中十分的重要,如果这两个例子不能帮助你理解的话,你可以看一下大牛Yuan先生博客,里面讲的很通彻
例子1:
计算函数运行的时间
import time def show_time(f): def out(*x,**y): start = time.time() f(*x,**y) end = time.time() print "spend time:%s"%(end-start) return out @show_time # f=show_time(f) def f(*a,**b): sums=0 for i in a: sums+=i print sums time.sleep(1) f(1,2,7,4) 运行结果: 14 spend time:1.0
例子2
增加难度,再添加一个参数
import time def log(flag): def show_time(f): #2.show_time(f,flag) def out(*x,**y): start = time.time() f(*x,**y) end = time.time() run = end-start print "spend time:%s"%(run) if flag=="True": with open("text","a") as ji: ji.write("\nspend time:%s"%(run)) return out return show_time @log("True") #@out out(f) # 1.@封装的只能传一个参数,只要满足闭包的定义就能运行,返回值show_time,就相当于@show_time, def f(*a,**b): #2,不用@多加一个参数也可以 sums=0 for i in a: sums+=i print sums time.sleep(1) f(1,2,7,4) 运行结果: 14 spend time:1.00099992752
【列表生成式】
print [ i*i for i in range(0,19)] 运行结果: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324]
【生成器(generator)】
生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅
生成器一定是迭代器,迭代器不一定是生成器
生成器的创建:()或 yield
下边的斐波那契数列会让你更好的体会生成器,生成器的调用时用next()方法,生成器就是平常不会运行,只有调用的时候才会运行,而且因为python的回收机制,使得生成器在内存中只有自己的一条数据可以更好地对内存进行利用
s=((x for x in range(2))) #yield print next(s) 运行结果: 0 def fib(max): n,before,after = 0,1,1 while n<max: # print after yield after #就成了生成器了 before,after = after,before+after n+=1 a=fib(10) print next(a) 运行结果: 1
【生成器的send() 方法】
send()方法是对yeild的前边的变量进行赋值
def f(): print "aa" count = yield 1 print count yield 2 b = f() next(b) ret =b.send("bb") #可以给yeild前边的变量赋值 print ret 运行结果: aa bb 2
【迭代器】
定义L: 1.有iter方法 2.有next方法
for 内部做的三件事: 1。调用可迭代对象的iter方法,返回一个迭代器对象 2.不断调用next方法 3处理StopIteration异常