19 python基础--函数式编程
发布日期:2021-05-14 12:22:33 浏览次数:20 分类:精选文章

本文共 6869 字,大约阅读时间需要 22 分钟。

文章目录

1. 函数式编程(FunctionalProgramming)

  • 基于lambda演算的一种编程方式
    • 程序中只有函数
    • 函数可以作为参数,同样可以作为返回值
    • 纯函数式编程语言: LISP, Haskell
  • Python函数式编程只是借鉴函数式编程的一些特点,可以理解成一半函数式一半Python

2. lambda匿名函数

  • 函数: 最大程度复用代码

    • 存在问题: 如果函数很小,很短,则会造成啰嗦
    • 如果函数被调用次数少,则会造成浪费
    • 对于阅读者来说,造成阅读流程的被迫中断
  • lambda表达式(匿名函数):

    • 一个表达式,函数体相对简单
    • 不是一个代码块,仅仅是一个表达式
    • 可以有参数,有多个参数也可以,用逗号隔开
# lambda表达式的用法    1. 以lambda开头    # 2. 紧跟一定的参数(如果有的话)    # 3. 参数后用冒号和表达式主题隔开    # 4. 只是一个表达式,所以,没有returnnum  = lambda x,y,z: x * 100 + y * 10 + zs = num(1,2,3)print(s)>123

3. 高阶函数

  • 把函数作为参数使用的函数,叫高阶函数
##定义函数需要扩大100倍def funA(n):    return n * 100##定义函数需要扩大300倍def funB(n, f):    # 假定函数是把n扩大100被  return f(n) * 3print( funB(9, funA) )>2700
  • 高阶函数-map
  • 原意就是映射,即把集合或者列表的元素,每一个元素都按照一定规则进行操作,生成一个新的列表或者集合
  • map函数是系统提供的具有映射功能的函数,返回值是一个迭代对象
  • 语法:map(func, *iterables) --> map object
def f(x):    return x * xl = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])for i in l:    print(i,end=' ')>1 4 9 16 25 36 49 64 81
  • 高阶函数-reduce
  • 原意是归并,缩减,把一个可迭代对象最后归并成一个结果
  • 对于作为参数的函数要求: 必须由两个参数,必须由返回结果
  • reduce([1,2,3,4,5]) == f(f(f(f(1,2),3),4),5)
  • python3中使用reduce需要导入functools包
from functools import reducedef add(m,n):    return m + nl = reduce(add,[1,2,3,4,5,6])print(l)>21
  • 高阶函数-filter 函数
  • 过滤函数: 对一组数据进行过滤,符合条件的数据会生成一个新的列表并返回
  • 跟map相比较:
    • 相同:都对列表的每一个元素逐一进行操作
    • 不同:
      • map会生成一个跟原来数据想对应的新队列
      • filter不一定,只要符合条件的才会进入新的数据集合
    • filter函数怎么写:
      • 利用给定函数进行判断
      • 返回值一定是个布尔值
      • 调用格式: filter(f, data), f是过滤函数, data是数据
# 对于一个列表,对其进行过滤,偶数组成一个新列表# 需要定义过滤函数要求有输入,返回布尔值def isEven(a):    return a % 2 == 0l = [3,4,56,3,2,3,4556,67,4,4,3,23455,43]rst = filter(isEven, l)# 返回的filter内容是一个可迭代对象print(type(rst))print(rst)print([i for i in rst])>
[4, 56, 2, 4556, 4, 4]
  • 高阶函数-排序
  • 把一个序列按照给定算法进行排序
  • key: 在排序钱对每一个元素进行key函数运算,可以理解成按照key函数定义的逻辑进行排序
  • 语法:sorted(iterable, /, *, key=None, reverse=False)
a = [-43,23,45,6,-23,2,-4345]b = sorted(a,key= abs,reverse=True)print(b)>[-4345, 45, -43, 23, -23, 6, 2]

3. 返回函数

  • 函数可以返回具体的值
  • 也可以返回一个函数作为结果
# 函数作为返回值返回, 被返回的函数在函数体内定义def myFun1():    def myFun2():        print('In myFun2')        return 2    return myFun2a = myFun1()print(type(a))print(a)a()>
.myFun2 at 0x01386390> In myFun2--------------------------------------------------------------def myFun3(*args): def myFun4(): sum = 0 for i in args: sum += i return sum return myFun4()b = myFun3(1,2,3,4,5,6,7,8,9)print(b)>4950
  • 闭包(closure)
  • 当一个函数在内部定义函数,并且内部的函数应用外部函数的参数或者局部变量,当内部函数被当做返回值的时候,相关参数和变量保存在返回的函数中,这种结果,叫闭包
# 闭包常见坑def count():    # 定义列表,列表里存放的是定义的函数    fs = []    for i in range(1,4):        # 定义了一个函数f # f是一个闭包结构    def f():        return i*i        fs.append(f)    return fsf1,f2,f3 = count()print(f1())print(f2())print(f3())>9 9 9
  • 出现的问题:
  • 造成上述状况的原因是,返回函数引用了变量i, i并非立即执行,而是等到三个函数都返回的时候才统一使用,此时i已经变成了3,最终调用的时候,都返回的是 3*3
  • 此问题描述成:返回闭包时,返回函数不能引用任何循环变量
  • 解决方案: 再创建一个函数,用该函数的参数绑定循环变量的当前值,无论该循环变量以后如何改变,已经绑定的函数参数值不再改变
# 修改上述函数def count2():    def f(j):        def g():            return j*j        return g    fs = []    for i in range(1,4):        fs.append(f(i))    return fsf1,f2,f3 = count2()print(f1())print(f2())print(f3())>1 4 9

4. 装饰器

  • 在不改动函数代码的基础上无限制扩展函数功能的一种机制,本质上讲,装饰器是一个返回函数的高阶函数
  • 装饰器的使用: 使用@语法, 即在每次要扩展到函数定义前使用@+函数名
  • 好处:一点定义,则可以装饰任意函数,且把装饰器的功能直接添加到定义函数的功能上
def hello():    print("Hello world")# 调用hello()# 复制给函数f,并掉用f = hellof()## f 和hello是一个函数print(id(hello))print(id(f))print(hello.__name__)print(f.__name__)>Hello world Hello world 10160216 10160216 hello hello---------------------------------------------------------------def hello(f):    def word(*args, **kwargs):        print("Hello everyone,Good morning!")        return f(*args, **kwargs)    return word@hellodef weekday():    print('Today is Wednesday')weekday()@hellodef weather():    print('Today in fine!')weather()>Hello everyone,Good morning! Today is Wednesday>Hello everyone,Good morning! Today in fine!
  • 装饰器手动执行示例
##手动执行def hello(f):    def word(*args, **kwargs):        print("Hello everyone,Good morning!")        return f(*args, **kwargs)    return worddef weekday():    print('Today is Wednesday')a = hello(weekday)a()>Hello everyone,Good morning! Today is Wednesday

5. 偏函数

  • 参数固定的函数,相当于一个由特定参数的函数体
  • functools.partial的作用是,把一个函数某些函数固定,返回一个新函数,方便调用
import functoolsint16 = functools.partial(int,base = 16)print(int(234324))print(int16('234324'))>234324>2310948

6. 高阶函数补充

  • zip
  • 把两个可迭代内容生成一个可迭代的tuple元素类型组成的内容
z1 = [1,2,3,4,5,6]z2 = [11,22,33,44,55,66]z = zip(z1,z2)print(type(z))print(z)z0 = [i for i in z]print(z0)>
[(1, 11), (2, 22), (3, 33), (4, 44), (5, 55), (6, 66)]
  • enumerate
  • 跟zip功能比较像
  • 对可迭代对象里的每一元素,配上一个索引,然后索引和内容构成tuple类型
l1 = [11,22,33,44,55]em = enumerate(l1,start=200)l2 = [i for i in em]print(l2)>[(200, 11), (201, 22), (202, 33), (203, 44), (204, 55)]
  • collections模块-----namedtuple
  • tuple类型,是一个可命名的tuple
import collectionsa = collections.namedtuple('b',['x','y'])c = a(1,2)print(c.x)print(c[0])d = c.x + c.yprint(d)>1 1 3
  • collections模块-----deque
  • 比较方便的解决了频繁删除插入带来的效率问题
from collections import dequeq = deque(['a', 'b', 'c'])print(q)q.append("d")print(q)q.appendleft('x')print(q)>deque(['a', 'b', 'c']) deque(['a', 'b', 'c', 'd']) deque(['x', 'a', 'b', 'c', 'd'])
  • collections模块-----defaultdict
  • 当直接读取dict不存在的属性时,直接返回默认值
from collections import defaultdictfunc = lambda :'该键值对不存在,返回默认值替代"KeyError"'a = defaultdict(func)a['one'] = 1a['two'] = 2print(a['one'])print(a['three'])>1 该键值对不存在,返回默认值替代"KeyError"
  • collections模块-----Counter
  • 统计字符串个数
from collections import Countera = Counter('weqweqfsdvfsdgrdthdgbhdtsdfs')print(a)>Counter({   'd': 6, 's': 4, 'f': 3, 'w': 2, 'e': 2, 'q': 2, 'g': 2, 't': 2, 'h': 2, 'v': 1, 'r': 1, 'b': 1})

7. 递归函数

定义:函数Func(Type a,…)直接或间接调用函数本身,则该函数称为递归函数.

def fun(n):    if n == 1 or n == 2: # 递归临界点,不再调用自身函数的条件        return 1    else:        return fun(n-1) + fun(n-2)l = []for i in range(1, 10):    l.append(fun(i))print(l)>[1, 1, 2, 3, 5, 8, 13, 21, 34]

递归的弊端:递归函数用很少的代码完成了庞大的功能,但大量的重复计算导致时间与空间的消耗。同时递归深度存在一定限制。

# 方式一: 缓存优化def cache_decorator(func):    cache_dict = {   }    def decorator(arg):        try:            return cache_dict[arg]        except KeyError:            return cache_dict.setdefault(arg, func(arg))    return decorator@cache_decoratordef fun(n):    if n == 1 or n == 2:        return 1    else:        return fun(n-1) + fun(n-2)l = []for i in range(1, 30):    l.append(fun(i))print(l)
# 方式二: 缓存优化from functools import lru_cache@lru_cachedef fun(n):    if n == 1 or n == 2:        return 1    else:        return fun(n-1) + fun(n-2)l = []for i in range(1, 30):    l.append(fun(i))print(l)

8. 纯函数

纯函数:一个函数的返回结果只依赖其参数,并且执行过程中没有副作用

函数的副作用:函数完成既定任务的同时,访问了外部数据,尤其是对外部数据进行了写操作,改变了系统环境。
纯函数的3个原则:1、 变量只在作用域内获取,作为参数传入;2、不会产生副作用;3、相同的输入保证相同的输出

def func(a ,b):    return a + b

9. 内置函数

官方文档: https://docs.python.org/zh-cn/3/library/functions.html

# filterl = [1, 33, 45, 34, 77]def func(n):    return n < 35r = filter(func, l)print(list(r))>[1, 33, 34]
# filterl = [1, 33, 45, 34, 77]def func(n):    return n*2r = map(func, l)print(list(r))>[1, 33, 34]
上一篇:20 python基础--调试
下一篇:18 python基础--库calender+shutil+zipfile

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2025年04月13日 19时13分40秒