Python高级语法——函数式编程——学习心得笔记
1. 函数式编程(FunctionalProgramming)
1.1. 基于lambda演算的一种编程方式
-
程序中只有函数
-
函数可以作为参数,同样可以作为返回值
-
纯函数式编程语言:LISP, Haskell
-
Python函数式编程只是借鉴函数式编程的一些特点,可以理解为一半函数式一半Python
-
常用函数
- 高阶函数
- 返回函数
- 匿名函数
- 装饰器
- 偏函数
-
lambda表达式
-
函数:最大程度复用代码
- 存在问题: 如果函数很小很短,则会造成啰嗦
- 如果函数被调用次数少,则会造成浪费
- 对于阅读者来说,造成阅读流程的被迫中断
- 看实例 小函数
-
lambda表达式(匿名函数)
- 一个表达式,函数体相对简单
- 不是一个代码块,仅仅是一个表达式
- 可以有参数,有多个参数也可以,用逗号隔开
- 看实例
1.2. 高阶函数
-
把函数作为参数使用的函数,叫高阶函数
-
看实例
-
系统高阶函数
-
map: 映射
- 即把集合或者列表中的元素,每一个元素都按照一定的规则进行操作,生成一个新的
列表或者集合 - map函数是系统提供的具有映射功能的高阶函数,返回值是一个迭代对象
- 看实例
- 即把集合或者列表中的元素,每一个元素都按照一定的规则进行操作,生成一个新的
-
reduce: 归并,缩减
- 把一个可迭代的对象最后归并成一个结果
- 对于函数参数有要求:
- 必须有两个参数,必须有返回结果
= 看实例
-
filter: 过滤函数
- 对一组数据进行过滤,符合条件的数据会生成一个新的列表并返回
- 看实例
-
排序
- python内置函数(sort()、sorted()、argsort()
- 高阶函数排序:把一个序列按照给定算法进行排序
-
返回函数
- 函数作为函数值返回
- 看实例
-
闭包(closure)
**
实例
**
# Python高级语法——函数式编程
# '小'函数举例
def printA():
print("AAAAA")
printA()
# lambda表达式(匿名函数)
# 以lambda开头
# 紧跟一定的参数,如果有的话
# 参数后用冒号和表达式主题隔开
# 只是一个表达式,所以没有return
# 计算一个数字的100倍
stm = lambda x: 100 * x
# 使用上跟调用函数一模一样
print(stm(100))
# 下式也可以定义为一个函数,返回一个值,但是表达式会比这个复杂的多
stm1 = lambda x, y, z: x + y * 10 + z * 100
print(stm1(4, 5, 6))
# 高阶函数,函数作为参数使用的函数
# 函数名称就是一个变量
def funA():
print("In funA")
funB = funA
funA()
funB()
# 高阶函数举例
# funA是普通函数,返回一个传入数字的100倍的数字
def funA(n):
return n * 100
# 在写一个普通函数,把传入的函数乘以300倍
def funB(n):
return funA(n) * 3
print(funB(9))
# 写一个高阶函数,f = funA
def funC(n, f):
# 假定函数是把n扩大100倍
return f(n) * 3
print(funC(9, funA))
# 比较funC和funB,显热funC更灵活
# 例如n现在要放大30倍
# 如果要调用funB,需要修改funB的函数本体
def funD(n):
return n * 10
print(funC(9, funD))
# map映射实例
l1 = [i for i in range(10)]
print(l1)
l2 = []
for i in l1:
l2.append(i * 10)
print(l2)
# map实现上述功能
l1 = [i for i in range(10)]
def mulTen(n):
return n * 10
l3 = map(mulTen, l1)
for i in l3:
print(i)
print(l3)
# reduce实例
from functools import reduce
def myAdd(x, y):
return x + y
# 对于列表[1, 2, 3, ....]执行,前一个加一个一直结束返回一个值
# 1到100的数字相加
rst = reduce(myAdd, [i for i in range(101)])
print(rst)
# filter函数
# 定义过滤函数
# 过滤函数要求有输入,返回布尔值
def isEven(a):
return a % 2 == 0
l = [3, 3, 3, 45, 23, 54, 63, 24, 67, 5, 5, 6, 9, 8, 8]
rst = filter(isEven, l)
print(type(rst))
print(rst)
# 返回的就是filter数据,数据都进行了包装
# 采用for循环提取数据
print([i for i in rst])
# 排序案例
l = [3, 45, -7, 23, 54, -43, -78, 63, 24, 67, -120, 5, 6, 9, 8]
# 正序
al = sorted(l)
print(al)
# 倒序
al = sorted(l, reverse=True)
print(al)
# 按照绝对值排序
al = sorted(l, key=abs, reverse=True)
print(al)
# sorted案例
astr = ['abc', 'Tian', 'hafj', 'Xixi']
str1 = sorted(astr)
print(str1)
str2 = sorted(astr, key=str.lower)
print(str2)
# 函数作为值返回
def myF2():
def myF3():
print("In myF3")
return 3
return myF3
f3 = myF2()
print(type(f3))
print(f3)
1.3. 装饰器(decrator)
- 在不改动函数代码的基础上次无限扩展函数功能的一种机制
- 本质上讲,装饰器是一个返回函数的高阶函数
- 装饰器语法:
- 使用@语法,即在每次要扩展到函数定义前使用@+函数名
- 看实例23_2.py
- 装饰器的好处:
- 一旦定义,则可以装饰任意函数
- 一旦被其装饰,则把装饰器的功能直接添加到定义的函数上
**
实例23_2
**
# 装饰器
# 对hello函数进行扩展
# 高阶函数,以函数作为参数
import time
def printTime(f):
def wrapper(*args, **kwargs):
print("Time: ", time.ctime())
return f(*args, **kwargs)
return wrapper()
# 上面定义了一个装饰器。调用需要使用@
# hello函数就进行了扩展
@printTime
def hello():
print("Hello world!")
hello
@printTime
def hello1():
print("Hello world!")
hello1
# 偏函数
# 把字符串转化为十进制数字
l = int("12345")
# print(l)
# 求八进制的字符串12345,表示成十进制的数字是多少
l = int("12345", base=8)
# print(l)
# 新建一个函数,函数默认输入的是的字符串是16进制的数字
# 把此字符串转化成十进制和八进制的数字
def int16(x, base=16):
return int(x, base)
print(int16("12345"))
def int10(x, base=16):
return int(x, base=8)
print(int10("12345"))
# 偏函数
import functools
# 实现上面int16的功能
int16 = functools.partial(int, base=16)
print(int16("12345"))
# 高级函数补充
# zip实例
l1 = [1, 2, 3, 4, 5]
l2 = [11, 22, 33, 44, 55]
l3 = zip(l1, l2)
print(type(l3))
print(l3)
for i in l3:
print(i)
l1 = ['zhangfei', 'lisi', 'zhuergou']
l2 = [56, 76, 98]
l3 = zip(l1, l2)
for i in l3:
print(i)
# enumerate实例
# 每个值添加一个索引
l1 = [1, 2, 3, 4, 5]
em = enumerate(l1)
l2 = [i for i in em]
print(l2)
em = enumerate(l1, start=100)
l2 = [i for i in em]
print(l2)
1.4. 偏函数
- functools.partial()
- 作用:把一个函数的某些函数或者参数固定,返回一个新函数
- 看实例
1.5. 高级函数补充
- zip 把两个可迭代内容生成一个可迭代的tuple元素类型组成的内容
- enumerate 根zip功能很像,可迭代对象里的每一个元素,配上一个索引,然后索引和内容构成一个tuple类型
- collection
- namedtuple: 是一个可命名的tuple
- deque: 解决了频繁删除和插入带来的效率问题
- defaultdict: 当直接读取dict不存在的属性时,直接返回默认值
- counter: 统计字符串中每个字符出现的个数,并返回一个字典
- 看实例23_3.py
实例23_3
# collection模块
# namedtuple
import collections
# help(collections.namedtuple)
# 定义一个点
Point = collections.namedtuple("Point", ['x', 'y'])
p = Point(11, 12)
print(p.x)
print(p.y)
print(p[0])
print(p[1])
# 定义一个圆
Circle = collections.namedtuple("Circle",['x', 'y', 'r'])
c = Circle(100, 150, 50)
print(c)
print(c.x)
print(type(c))
# c是不是一个tuple(元组)
i = isinstance(c, tuple)
print(i)
# dequeue
from collections import deque
q = deque(['a', 'b', 'c'])
print(q)
q.append('d')
q.appendleft('x')
print(q)
# defaultdict
from collections import defaultdict
func = lambda: "Felix"
d2 = defaultdict(func)
print(d2['one'])
print(d2['four'])
# Counter统计每个字符出现的个数,返回字典
from collections import Counter
c = Counter('abcfeafffefaljdfjakdjkdjdkkd')
print(c)
1.6. 调试技术
- 调试流程:单元测试->集成测试->交测试部
- 分类:
- 静态调试:
- 动态调试:
- pycharm调试
- run: 全部运行模式
- debug: 调试模式
- 断点:程序的某一行,程序在debug模式下,遇到断点就会暂停
来源:CSDN
作者:夏树柏
链接:https://blog.csdn.net/u011318077/article/details/86500768