zoukankan      html  css  js  c++  java
  • 函数式编程

    函数式编程

    高阶函数
    map, filter, sorted
    递归 recursion

    闭包 closure

    函数式编程

    函数式编程
    函数式编程是指用一系列函数解决问题
    好处:
    1.用每一个函数完成细小的功能, 一系列函数的任意组合可以完成大问题
    2.函数仅接受输入并产生输出, 不包含任何能影响输出的内部状态

    函数是一等公民(Guido)
    1.函数本身可以赋值给变量,赋值后变量绑定函数
    2.允许将函数本身作为参数传入另一个函数
    3.允许函数返回一个函数

    函数的可重入性
    如果一个函数的输入参数一定, 则返回结果必须一定的函数称为可重入函数

    #可冲入函数,传入函数一定,结果必然一定 
    def myadd(x, y):
    return x+y


    #不可重入函数
    y =200
    def myaddd#引用了外部变量, 变成不可重函数
    return x + y
    print(myadd(10))


    函数编程的要求:
    def创建的函数最好不要访问局部作用域以外的变量,这样可以保证返回结果的唯一性(可重入性)

    测试  调试

    s = sum(range(1, 101))
    1~100的和

    例:
    可重入函数:
    def add1(x,y) # 尽量用可重入函数
    return x+y

    add1(100,200)

    不可重入函数
     y=200 # 引用了外部变量 变成不可重入函数
    def add2(x):
    return x+y
    print(add2(10)) # 210
    y=300
    print(add2(10)) #310


    高阶函数

    High Order Function

    指满足下列条件之一的即为高阶函数
    1.函数接受一个或多个函数作为参数传入
    2.函数返回一个函数
    >>> def fx(fn, L):
    ...   return fn(L)
    ...
    >>> fx(sum, [1, 2, 3, 4])
    10
    >>> fx(100, 200)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 2, in fx
    TypeError: 'int' object is not callable

    >>> def fy():
    ... def hello():
    ... print("hello world")
    ... return hello#加括号不是返回函数, 而是调用后的返回结果

     


    python内建函数的高阶函数


    map,   filter,   sorted

    高阶函数 High Order Function
    函数说明作用

    map(func, *iterables) 用函数和对可迭代对象中的每一个元素作为参数计算出新的可迭代对象,当最短的一个可迭代对象不再提供数据时此可迭代对象生成结束

    filter(function, iterable) 过滤
    筛选可迭代对象iterable中的数据,返回一个可迭代器对象,此可迭代对象将对iterable进行筛选.函数function 将对iterable中的每个元素进行求值,返回False则将此数据丢弃,返回True,则保留此数据

    sorted(iterable, key=None, reverse=False) 将原可迭代对象的数据进行排序,生成排序后的列表iterable 可迭代对象
    key 函数是用来提供一个值,这个值将作为排序的依据reverse 标志用来设置是否降序排序


    map函数


    格式
    map(func,*iterables)

    *iterables星号元组形参
    =def map(fn, *args):
    ...

    用函数和对可迭代对象中的每一个元素作为参数返回新的可迭代对象,当最短的一个可迭代对象不再提供数据是迭代结束
      要求:
         func函数接收的参数个数必须与可迭代对象的个数相同

    例:

     1 # 生成一个可迭代对象, 此可迭代对象可以生成1~9自然数的平方#1 4 9 16 。。。81
     2 
     3 L = []
     4 a = int(input('请输入:'))
     5 def power2(x):
     6     return x**2
     7 
     8 for x in map(power2, range(1, a+1)):
     9     L.append(x)
    10 print(L)
    map.py
    1 # 生成1**3  2**3   3**3
    2 def power3(x):
    3     return x**3
    4 
    5 for x in map(power3, range(1, 10)):
    6     print(x)
    map.py
    for x in map(lambda x: x**4, range(1, 10)):
        print(x)

    练习

    用map函数1**3+2**3+3**3+.....9**3的和
    用map函数1**4+2**4+3**4+....20**4的和
    用sum(map(....))

     1 print(sum(map(lambda x : x**3, range(1, 10))))
     2 
     3 s = 0
     4 for x in range(1, 10):
     5     s += x**3
     6 print('和是:', s)
     7 
     8 s = 0
     9 for x in map(lambda x : x**3, range(1, 10)):
    10     s += x
    11 print('和是:', s)
    12 
    13 
    14 s = sum(map(lambda x : x**3, range(1, 10)))
    15 print('和是:', s)
    三次方和
    1 def power20(x):
    2     return x**4
    3 print(sum(map(power20, range(1, 21))))
    四次方和

    说明:

    >>> pow(1, 9)
    1#1**9
    >>> pow(2, 3)
    8#2**3

     1 #生成可迭代对象
     2 # 1**4, 2**3, 3**2, 4**1
     3 def pow_a_b(a, b):
     4     return a ** b
     5 
     6 for x in map(power_a_b, 
     7             [1, 2, 3, 4], #可加5, 6, 7, 8
     8             [4, 3, 2, 1])
     9     print(x)
    10 
    11 
    12 def power_a_b(a,b):
    13     return a ** b
    14 for x in map(power_a_b,
    15              [1,2,3,4,5,6,7,8], # 按最短的可迭代对象
    16              [4,3,2,1]):
    17     print(x)
    18 
    19 L=list(map(pow,range(1,10),range(9,0,-1)))
    20 print(L) # 生成列表
    21 
    22 def k_v(a,b):
    23     return (a,b)
    24 d=dict(map(k_v,range(1,10),range(9,0,-1)))
    25 print(d) # 生成字典
    map生成对象

    filter函数

    filter(function, iterable)

    1 # filter 函数示例
    2 # 写一个函数,判断x 是否为奇数,奇数返回True ,偶数返回False
    3 
    4 def is_odd(x):
    5     if x % 2 == 1:
    6         return True
    7     return False

    例:
    写一个函数判断是否为奇数

    1 def is_odd(x):
    2     if x % 2 == 1:
    3         return True
    4     return False

    返回可迭代对象
    range(..)
    map(..)
    filter(..)
    reversed(..)

     1 # 求1**9+2**8+3**7....9**1
     2 
     3 def isodd(x):
     4     return x % 2 == 1
     5 for x in filter(isodd, range(41, 53)):
     6     print(x)
     7 
     8 s = 0
     9 for x in map (pow, range(1, 10), range(9, 0, -1)):
    10     s +=x
    11     print(x)
    12 print(s)
    13 
    14 
    15 # 终端运行
    16 >>> s = 0
    17 >>> for x in map (pow, range(1, 10), range(9, 0, -1)):
    18 ...     s +=x
    19 ...     print(x)
    20 ... 
    21 # 1
    22 # 256
    23 # 2187
    24 # 4096
    25 # 3125
    26 # 1296
    27 # 343
    28 # 64
    29 # 9
    30 # >>> s
    31 # 11377
    1~9的9~1次方


    >>> list(map (pow, range(1, 10), range(9, 0, -1)))
    [1, 256, 2187, 4096, 3125, 1296, 343, 64, 9]

     生成1~10以内的奇数列表#[1, 3 5 7 9]

    1 for x in filter(is_odd, range(1, 10)):
    2     print(x)
    3 
    4 L = [x for x in filter(is_odd, range(1, 10))]
    5 print(L)#[1, 3, 5, 7, 9]

    sorted函数

    作用:
       将原可迭代对象提供的数据进行排序,生成排序后的列表
    格式:
      sorted(iterable,key=None,reverse=False)
    说明:
       iterablek 可迭代对象
       key 函数是用来提供一个排序参考值的函数,这个函数的返回值将作为
    排序的依据
    reverse 标志用来设置是否降序排序
    示例:
     L = [5,-2,-4,0,3,1]
    L2 = sorted(L) # [-4,-2,0,1,3,5]
    # 要得到这样的结果该怎么办?
    #[0,1,-2,3,-4,5]
    L3 = sorted(L,key=abs)

    names = ['Tom','Jerry','Spike','Tyke']
    #结果['Tom','Tyke','Jerry','Spike']
    L = sorted(name) # 按名字首字母排序
    L = sorted(name,key=len) # 按名字长短


    练习:
      已知:
       names = ['Tome','Jerry','Spike','Tyke']
      排序的依据为原字符串反序的字符串

    names = ['Tom','Jerry','Spike','Tyke']
    def get_key(n):
    '''n用来绑定参数中每个元素,n绑定名字(字符串)
    此函数需要返回一个能比较大小的依据'''
        return n[::-1]
    L=sorted(names,key=get_key)
    print(L)
    结果['Spike', 'Tyke', 'Tom', 'Jerry']
    fangfa2
    L=sorted(names,key=lambda n:n[::-1])
    print(L)

     1 names = ["Tom", 'Jerry', 'Spike', 'Tyke']
     2 L1 = sorted(names, key=lambda x : x[::-1])#有双::是顺序翻过, 无冒号则最后一个字母
     3 print(L1)
     4 ['Spike', 'Tyke', 'Tom', 'Jerry']
     5 
     6 
     7 names = ["Tom", 'Jerry', 'Spike', 'Tyke']
     8 def k(s):
     9     return s[::-1]
    10 
    11 L = sorted(names, key = k)
    12 print(L)
    名字排序

    练习:

    1.将1~20 的偶数用filter 生成可迭代对象后将可迭代对象生成的数
    放入到列表 L中

    filter

    2.写一个函数 is_prime(x),判断x 是否是素数,用 函数打印出:
    20~30 之间的全部素数

     filter
     1 # sorted.py
     2 
     3 L = [5, -2, -4, 0, 3, 1]
     4 L2 = sorted(L)#L = [-4, -2, 0, 1, 3, 5]
     5 L3 = sorted(L, reverse=True)#L = [-4, -2, 0, 1, 3, 5]降序排序
     6 
     7 L4 = sorted(L, key=abs)
     8 #L4 = [0, 1, -2, 3, -4, 5]
     9 print(L4)
    10 L5 = sorted(L, key=abs, reverse=True)
    11 print(L5)#[5, -4, 3, -2, 1, 0]
    12 
    13 # "abs"去绝对值
    14 
    15 
    16 
    17 # sorted2.py
    18 
    19 names = ["Tom", 'Jerry', 'Spike', 'Tyke']
    20 
    21 L1 = sorted(names)
    22 print('L1', L1)
    23 # L1 ['Jerry', 'Spike', 'Tom', 'Tyke']
    24 
    25 L2 = sorted(names, key=len)
    26 print("L2", L2)
    27 # L2 ['Tom', 'Tyke', 'Jerry', 'Spike']
    28 
    29 L3 = sorted(names, key=lambda x : len(x))
    30 # print("L3", L3)
    31 L3 ['Tom', 'Tyke', 'Jerry', 'Spike']
    sorted.py


    递归函数recursion

    函数直接或间接的调用函数自身

    >>> def story():
    ... print("congqianyouzuosan, 山上有座庙。。。")
    ... story()
    ...
    >>>
    >>> story()


    递归的事例
    函数直接调用自己
    def f():
      f()#调用自己
    f()

    #函数间接的调用自己
    def fa():
      fb()
    def fb():
      fa()
    fa()
    print("递归完成")

    递归说明:
    递归一定要控制递归的层数, 当符合一定条件时要终止递归几乎所有的递归都能用while循环来代替

    优缺点
    优点:
    递归吧问题简单化, 让思路更为清晰, 代码更简洁
    缺点:
    递归因系统环境影响大, 当递归深度太大时, 可能回得到不可预知的结果

    递归的两个阶段:
     递推阶段:从原问题出发,按递归公式递推从未知到已知,最终达到递归的          终止条件
     回归阶段:按递归终止条件求出结果,逆向逐步代入递归公式,回归到问题           求解

    示例:

    1 def fn(n):
    2     print("递归进入第",n,'')
    3     if n == 3: # 当递归进入第三层时,将不再向下走,开始回归
    4         return 
    5     fn(n+1) 
    6     print("递归退出第",n,'')
    7 
    8 fn(1)
    9 print("程序结束")


    示例:
     写一个函数求n的阶乘(递归实现)
    # 1*2*3*4*5等同于5*4*3*2*1
    # 5!=5*4!...2!=2*1!

    1 def myfac(n):
    2     if n==1:
    3         return 1
    4     return n *myfac(n-1)
    5 
    6 print("5的阶乘是:",myfac(5))

    递归的实现方法:
     先假设函数已经实现


     写一个函数mysum(n),用递归方法求
    1+2+3+4+....+n的和

    1 def mysum(n):
    2     if n ==1:
    3         return 1
    4     return n+mysum(n-1)
    5 
    6 print(mysum(100))

    例:

     1 # recursion.py
     2 
     3 def fx(n):
     4     print("fx进入第", n, '')
     5     # fx(n+1)
     6     print("fx退出第", n, '')
     7 
     8 
     9 fx(1)
    10 print("程序结束")
    11 
    12 
    13 # fx进入第 1 层
    14 # fx进入第 2 层
    15 # fx进入第 3 层
    16 # fx进入第 4 层
    17 # fx进入第 5 层
    18 # fx进入第 6 层
    19 
    20 
    21 # fx进入第 995 层
    22 # fx进入第 996 层
    23 # fx进入第 997 层
    24 
    25 
    26 
    27 
    28 
    29 def fx(n):
    30     print("fx进入第", n, '')
    31     if n == 3:
    32         return
    33     fx(n+1)   
    34     print("fx退出第", n, '')
    35 
    36 
    37 fx(1)
    38 print("程序结束")
    39 
    40 # fx进入第 1 层
    41 # fx进入第 2 层
    42 # fx进入第 3 层
    43 # fx退出第 2 层
    44 # fx退出第 1 层
    45 # 程序结束
    recursion.py
     1 # 1.给出一个整数n,写一个函数来计算n!(n的阶乘)
     2 #  n! = 1*2*3*.....* n
     3 
     4 # n!=n*(n-1)*(n-2)*...3*2*1
     5 # 100!=100*99*98...3*2*1
     6 
     7 def fac(n):
     8     if n == 1:#当1!直接返回1
     9         return 1
    10     return n*fac(n-1)
    11 
    12 print(fac(5))
    13 # 120
    14 
    15 def fac(n):
    16     return n*(n-1)
    17 print(fac(5))
    18 
    19 # 20
    recursion_fac.pt

    递归练习:
    用递归方式实现求和 mysum(n)

     1 def mysum(n):
     2     if n ==1:
     3         return 1
     4     return n + mysum(n-1)
     5 
     6 print(mysum(100))
     7 
     8 
     9 s = 0
    10 for i in range(1, 101):
    11     s +=i
    12 print (s)
    13 
    14 
    15 print(sum(x for x in range(1, 101)))
    16 
    17 
    18 print(sum(map(lambda x : x, range(1, 101))))
    求和
    1 def friend(n):
    2     if n == 1:
    3         return 10
    4     return friend(n-1)+2
    5 
    6 print(friend(5))

    闭包closure
    闭包是指引用此函数外部的变量的函数
    说明:
    在本质上, 闭包是将内部嵌套函数和函数外部的执行环境绑定在一起的对象

    闭包

    闭包必须满足三个条件
    1.必须有一个内嵌函数
    2.内嵌函数必须引用外部函数中的变量
    3.外部函数返回值必须是内嵌函数

     1 # closure.py
     2 # 闭包示例:
     3 def make_power(y):
     4     def fn(arg):
     5         return arg ** y
     6     return fn
     7 
     8 
     9 pow2 = make_power(2)  # 请问pow2绑定的是什么?
    10 print('5的平方是:', pow2(5))  
    11 
    12 # 求1**2 + 2 ** 2 + 3 ** 2 + .... 100 ** 2
    13 print(sum(map(lambda x: x ** 2, range(1, 101))))
    14 print(sum(map(make_power(2), range(1, 101))))
    15 
    16 print("1 ** 3 + 2**3 + ...... + 100 ** 3=")
    17 print(sum(map(lambda x: x ** 3, range(1, 101))))
    18 print(sum(map(make_power(3), range(1, 101))))
    19 # print(sum(map(lambda x: x ** 3, range(1, 101))))

    求1**2+2***2+3**2+...100**2

     1 print(sum(map(lambda x : x ** 2, range(1, 101))))
     2 
     3 def make_power(y):
     4     def fn(arg):
     5         return arg ** y
     6     return fn
     7 
     8 print(sum(map(make_power(2), range(1, 101))))
     9 
    10 
    11 1**3+2***3+3**3+...100**3
    12 
    13 print(sum(map(lambda x : x ** 3, range(1, 101)))
    14 
    15 
    16 def make_power(y):
    17     def fn(arg):
    18         return arg ** y
    19     return fn
    20 
    21 print(sum(map(make_power(3), range(1, 101))))
    平方求和


    例:

    用闭包来创建函数

    示例:

     1 f(x) = a*x**2 + b*x + c
     2 
     3 def get_fx(a, b, c):
     4     def fx(x):
     5         return a * x ** 2 + b * x + c
     6     return fx
     7 
     8 f123 = get_fx(1, 2, 3)
     9 print(f123(20))
    10 print(f123(50))
    11 
    12 f654 = get_fx(6, 5, 4)
    13 print(f654(30))
    closure2.py

    闭包示例:

    def make_power(y):
        def fn(x):
            return x **y
        return fn
    pow2=make_power(2) # pow2绑定的是什么?
    print("5的平方是",pow2(5))  
    pow3=make_power(3)
    print("6的立方是",pow3(6))
    

      

    闭包的实例应用:
    用闭包来创建任意的f(x)=a * x ** 2 +b * x ** 1 + c的函数

     1 def get_fx(a,b,c):
     2     def fx(x):
     3         return a * x ** 2 + b * x ** 1 + c
     4     return fx
     5     
     6 #创建函数f(x)=1 * x** 2 + 2 * x ** 1+ 3
     7 f123=get_fx(1,2,3)
     8 print(f123(20)) # 443
     9 print(f123(50)) # 2603
    10 
    11 f654=get_fx(6,5,4)
    12 print(f654(10)) # 654
    13 print(f654(30)) # 5554


    练习:
    1.已知:
      第五个人比第四个人大2岁
      第四个人比第三个人大2岁
      第三个人比第二个人大2岁
      第二个人比第一个人大2岁
      第一个人说他10岁
    编写程序算出第五个人几岁
    (思考是否可以使用递归和循环两种方法来做)

     1 fangfa1 递归  
     2 def get_age(a):
     3  '''此函数返回第n个人多少岁'''
     4     if n ==1:
     5         return 10
     6     return get_age(n-1)+2
     7 print("第五个人%d岁" % get_age(5))
     8 
     9 fangfa2 循环
    10 def get_age(n):
    11     age=10
    12     for x in range(2,n+1):
    13         age += 2
    14     return age
    15 print("第五个人%d岁" % get_age(5))
    1 def pengyou(n):
    2     if n == 1:
    3         return 10
    4     return pengyou(n-1) + 2
    5 
    6 print(pengyou(5))
    7 print(pengyou(3))
    1

    2.已知有列表:
     L=[[3,5,8],10,[[13,14],15,18],20]
    1)写一个函数print_list(lst)打印出列表内的所有元素
    print_list(L) # 3,5,8,10,13..
    2)写一个函数sum_list(lst):
    返回这个列表中所有元素的和
    print(sum_list(L)) # 86
    注:type(x)可以返回一个变量的类型
    如:
    >>>type(20) is int # True
    >>>type([3,5,8]) is list # True

    1)

     1 1)
     2 L=[[3,5,8],10,[[13,14],15,18],20]
     3 def print_list(lst):
     4     for x in lst:
     5         if type(x) is int:
     6             print(x,end=' ')
     7         else:
     8             print_list(x) 
     9             # 递归调用处理内部列表
    10 print_list(L)
    11 print()

    2)

     1 def sum_list(lst):
     2     s=0  # 用于累加lst中的所有数的和
     3     for x in lst:
     4         if type(x) is int:
     5             s += x
     6         else:
     7             s += sum_list(x)
     8     return s # 返回当前的lst的结果
     9 
    10 print(sum_list(L))
     1 L = [[3,5,8],10,[[13,14],15,18],20]
     2 
     3 def print_list(lst):
     4     for x in lst:
     5         if type(x) is int:
     6             print(x,end= ' ')
     7         elif type(x) is list:
     8             print_list(x)
     9 
    10 print_list(L)
    2.1
     1 def sum_list(lst):
     2     s = 0
     3     for x in lst:
     4         if type(x) is int:
     5             s += x
     6         elif type(x) is list:
     7             s += sum_list(x)
     8     return s
     9 
    10 print(sum_list(L))
    2.2

    3.改写之前的学生信息管理程序
    要求添加四个功能:
    |5)按学生成绩高-低显示学生信息|
    |6)按学生成绩低-高显示学生信息|
    |7)按学生年龄高-低显示学生信息|

    |8)按学生成绩低-高显示学生信息|

  • 相关阅读:
    js练习题2
    js样式
    js小练习
    css动画样式
    css盒子、布局样式
    css一般样式
    css样式、选择器
    html表格、表单
    html 标签
    mysql连接查询,子查询,联合查询
  • 原文地址:https://www.cnblogs.com/Alan-Song/p/9668435.html
Copyright © 2011-2022 走看看