## python语言的高级特性
#函数式编程(Functional Programming)
-基于lambda演算的一种编程方式
-程序中只有函数
-函数可以作为参数,同样可以作为返回值
-纯函数式编程语言:LISP Haskell
-python函数式编程知识借鉴函数式编程的一些特点,可以理解为是一半函数一半python
-概念
-高阶函数
-返回函数
-匿名函数
-装饰器
-偏函数
#lambda表达式
-函数:最大程度复用代码
-存在的问题:如果函数很小,很短,采用函数式编程则会比较啰嗦
-如果函数被调用次数少,则会浪费
-对于阅读者来说,造成阅读过程的被迫中断
-lambda表达式(匿名函数):
-一个表达式,函数体相对简单
-不是一个代码块,仅仅是一个表达式
-可以有参数,有多个参数,用逗号隔开
#lambda表达式举例:
1、以lambda开头
2、紧跟一定的参数
3、参数后用冒号和表达式隔开
4、只是一个表达式,没有return
#计算一个数字的100倍数
stm = lambda X:100*X
stm(89) #使用时跟函数调用一样
##高阶函数
-把函数作为参数使用的函数,叫做高阶函数
#函数名称就是一个变量
def funcA():
print(" In funcA")
funcB = funcA
funcB()
#以上代码得出的结论:
-函数名称是变量
-funcB 和 funcA只是名称不同
-既然函数名称是变量,则可以被当做参数传入另一个函数
#高级函数举例
#funcA是普通函数,返回一个传入数字的100倍
def funcA(n):
return n*100
#再写一个函数,把传入参数乘以300倍,利用高阶函数
def funcB(n):
#最终是想返回300n
return funcA(n)#3
print(funcB(9))
#写一个高阶函数
def funcD(n,f):
#假设函数式把n扩大100倍
return f(n)*3
print(funcD(9,funcA))
#比较上述,funcD比funcB更灵活
##系统高阶函数
#map
-原意就是映射,把集合或者列表里的元素,每个元素都按照一定规则进行操作,生成一个新的列表或集合
-map函数是系统提供的具有映射功能的函数,返回值是一个迭代对象
#map 举例
#有一个列表,相对列表里的每个元素乘以10,并得到新的列表
l1 = [i for i in range(10)] print(l1) def multi(n): return n*10 l2 = map(multi,11) #map类型是一个可迭代的结构,所以也可以使用for循环 print(l2)
#reduce
-原意是归并,缩减
-把一个可迭代对象最后归并成一个结果
-对于参数有要求:必须有两个参数,必须有返回结果
-reduce([1,2,3,4,5]) == f(f(f(f(1,2),3),4),5)
-reduce 需要导入functools包
from functools import reduce #定义一个操作函数 #假设操作函数是用来相加 def siqi(x,y): return x+y #对于列表[1,2,3,4,5,6]执行siqi的reduce操作 rst = reduce(siqi,[1,2,3,4,5,6]) print(rst)
## filter 函数
-过滤函数:对一组数据进行过滤,符合条件的数据生成一个新的列表并返回
-跟map比较:
-相同:都对列表的每一个元素进行操作
-不同:
-map会生成一个跟原始列表相对应的新列表
-filter只有符合条件的才会留下
-filter函数写法:
-利用给定函数进行判断
-返回值一定是布尔值
-调用格式:filter(f,data),f是过滤函数,data是数据
#filter案例
#对于一个列表,对其进行过滤,偶数生成新列表
#需要定义过滤函数
#过滤函数要求有输入,返回布尔值
def siqi(a): return a%2 == 0 l = [1,2,3,4,5,7,23,56,445] rst = filter(siqi,l) #返回的filter内容是一个可迭代对象 print(rst) print([i for i in rst])
## 高阶函数-排序
-把一个序列按照给定的算法进行排序
-key:在排序前对每一个元素进行key函数运算
#排序案例-1 a = [234,546,234,56,765] siqi = sorted(a,reverse=True) print(siqi) #排序案例-2 a = [234,546,234,56,765,-2354,-234] #按照绝对值进行排序 #abs是求绝对值的意思 按照倒序排列 siqi = sorted(a,key=abs,reverse=True) print(siqi) #排序案例-3 astr = ["siqi","houzi","yong","qi"] bstr = sorted(satr) print(bstr) cstr = sorted(astr,key=str.lower) print(cstr)
## 返回函数
-函数可以返回具体的值
-也可以返回一个函数作为结果
#定义一个普通函数 def pangqi(a): print("aihouzi") return None a = pangqi(8) print(8) #函数作为返回值返回,被返回的函数在函数体内定义 def qi1(): def qi2(): print("aihouzi") return 3 return qi2 #使用上面定义的函数 #调用qi1,返回一个函数qi2,赋值给qi3 qi3 = qi2() print(qi3) qi3()
#复杂一点的返回函数的例子
#args:参数列表 #1、F4定义函数,返回内部定义的函数F5 #2、F5使用了外部变量,这个变量是F4的参数 def F4(*args): def F5(): rst = 0 for n in args: rst += n return rst return F5 F6 = F4(1,2,3,4,5,6,7,8,9,0) #F6的调用方式 F6()
##闭包(closure)
-当一个函数在内部定义函数,并且内部的函数应用外部函数的参数或者变量,当内部函数被当做返回值时,之前被应用的参数和变量保存在了返回的函数中,这种现象,称为闭包
-上述案例说明了闭包
-但返回闭包时,返回函数不能引用任何循环变量,如需要引用,必须在前面加一个函数固定住变量
#例
def count(): l = [] for i in range(3): def f(i): def g(): return i return g l.append(f(i)) return l f1, f2, f3 = count() print f1() print f2() print f3()
## 装饰器
def hello():
print("helloworld")
hello()
f = hello()
f()
# 现在有一个新的需求,
#对hello功能进行扩展,每次打印hello之前打印当前系统时间
#而实现这个功能,不能改动现有代码
#此时使用装饰器
-Decrator 装饰器
-装饰器的使用:使用@语法,@加函数名
代码实现:
import time def printTime(f): den wrapper(*args,**kwargs): print("Time:",time.ctime()) return f(*args,**kwargs) return wrapper #上面定义了装饰器,使用的时候需要用到@,次付好是python的语法糖 @printTime def hello(): print("hello world") hello() #装饰器的好处是一旦定义,则可以装饰任何函数 #一旦被其装饰,则把装饰器的功能直接添加到定义函数的功能上, @printTime def hello2(): print("pangqi is stupid") print("houzi is clever") hello2()
## 偏函数
#把字符串转化成十进制的数字
int("12345")
#八进制的字符串12345,把它表示成十进制
int("12345",base=8)
#新建一个函数,此函数默认输入的字符串是十六进制
#把字符串返回成十进制
def int16(x,base=16):
return in(x,base)
int16("12345")
#偏函数定义
-参数固定的函数。相当于有一个特定参数的函数体
-functools.partial的作用是,把一个函数某些参数固定,返回新函数
import functools
#实现上面int16的功能
int16 = functools.partial(int,base=16)
int16("12345")
#补充高阶函数
#zip
-把两个可迭代内容生成一个可迭代的tuple元素类型组成的元组 # zip案例-1 l1 = [1,2,3,4,5] l2 = [11,22,33,44,55] z = zip(l1,l2) print(zip) for i in z: print(i) # zip案例-2 l1 = ["siqi","houzi","haizi"] l2 = [99,60,100] z = zip(l1,l2) for i in z: print(i)
# enumerate
-跟zip功能类似,对可迭代对象里的每一个元素,配上一个索引,然后索引和内容构成tuple类型
#enumerate案例-1
l1 = [11,22,33,44,55] en = enumerate(l1) l2 = [i for i in en] print(l2) #enumerate案例-2 em = enumerate(l1,start=100) l2 = [i for i in em] print(l2)
#collections模块
-namedtuple
-deque
#namedtuple
-tuple类型 -是一个可命名的tuple import collections Point = collections.namedtuple("Point",["x","y"]) p = Point(11,22) print(p.x) print(p[0])
#deque
-比较方便的解决了频繁删除插入带来的效率问题
from collections import deque q = deque(["a","b","c"]) print(q) q.append("d") print(q) q.appendleft("x") print(q)
#defaultdict
-当直接读取dict不存在的属性时,直接返回默认值
form collections import defaultdict func = lambda:"siqi" d2 = defaultdict(func) d2 = {"one":1,"two":2,"three":3} print(d["four"])
#Counter
-统计字符串个数
from collections import Counter #需要括号里可迭代 c = Counter("awdrdwrfocjswoad") pring(c) s = ["siqi","love","houzi"] c = Counter(s) print(c)