(十一)python 高阶函数,递归,闭包

目录

eval 函数:

exec函数:

函数式编程:

高阶函数 high order function

    map 函数

    filter 函数:

    sorted 函数

递归函数    recursion

闭包  closure


eval 函数:

    作用:
        把一个字符串当成一个表达式来执行,返回表达式执行后的结果

    格式:
    eval(source,globals=None,locals=None)

x = 100
y = 200
while True:
    s = input("请输入表达式 >>> ")
    if not s:
        break
    v = eval(s)
    print(v)


x = 100
y = 200
v = eval('x + y')
print(v)  # 300

dict_local = {'x':1, 'y': 2}
v = eval('x + y', None, dict_local)
print(v)  # 3

dict_global = {'x':10, 'y': 20}
v = eval('x + y', dict_global, {'y':2})
print(v)  # 12


v = eval('x + y', None, {'y':2})
print(v)  # 12

v = eval('x + y', {'x':1})
print(v)  # 1 + y 出错

exec函数:

    作用:
        把一个字符串当成程序来执行
    格式:
        exec(source,globals=None,locals=None)

# 此示例示意exec函数的使用

x = 100
y = 200
s = '''z=x+y
print('z=', z)
print("hello world!")
'''
exec(s)  # 执行 s这个字符串
print(z)

dict_local = {'x': 1}
exec(s, None, dict_local)
print(dict_local)


函数式编程:

    函数式程序是指用一系列函数解决问题

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

    好处:
        用每一个函数完成细小的功能,一系列函数在任意组合可以完成大问题

    函数的可重入性:
        当一个函数在运行时不读取和改变除局部作用域以外的变量时,此函数为可重入函数
        可重入函数在每次调用时,如果参数一定,则结果必须一定

#示例:
可重入函数:
def add1(x,y):
    return x + y
不可重入函数:
y = 200
def add2(x):
    return x + y
print(add2(10))  #210
y = 300
print(add2(10))  #310


高阶函数 high order function

    什么是高阶函数
        满足下列条件中一个的函数即为高阶函数
            1.函数接收一个或多个函数作为参数传入
            2.函数返回一个函数
    python中内建的高阶函数:
        map,  filter,  sortde

    map 函数

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

def power2(x):
    return x ** 2

# 生成一个可迭代对象,此可迭代对象可以生成1~9的自然数的平方
for x in map(power2, range(1, 10)):
    print(x)

print('=================================')
L1 = [1, 2, 3, 4]
L2 = [5, 6, 7, 8, 9, 10]
# 生成一个可迭代对象,此可迭代对象生成的数据为:
#    1**5, 2**6, 3**7, 4**8
def power_x_y(x, y):
    return x + y

for x in map(power_x_y, L1, L2):
    print(x)  # 

练习:
    1.求1**2   + 2**2 + 3**2 + ... + 9**2的和
        (用函数式和高阶函数map实现)
    2.求1**3   + 2**3 + 3**3 + ... + 9**3的和
 
    3.求1**9   + 2**8 + 3**7 + ... + 9**1的和

#1.
  print(sum(map(pow,range(1,10),[2]*9)))
#2.
  s = 0
  for x in map(lambda x : x ** 3,range(1,10)):
      s += x
  print(s)
#3.
  print(sum(map(pow,range(1,10),range(9,0,-1))))

    filter 函数:

        格式:
            filter(function,iterable)
        作用:
            筛选可迭代对象iterable中的数据,返回一个可迭代对象,
            此可迭代对象将对iterable提供的数据进行筛选
            说明:
                函数function 将对iteralbe中的每个元素进行求布尔值,
                返回True则保留,返回False则丢弃

def isodd(x):  # 此函数判断x是否为奇数,如果是奇数返回True
    return x % 2 == 1

for x in filter(isodd, range(41, 53)):
    print(x)

练习:
    1.把之前的is_prime(x)判断x是否为素数的函数复制过来
        1)用filter 函数   把  100到200的全部素数求出来,放入列表L中
        2)求300 ~ 400之间全部素数的和

def is_prime(x):
    '''判断x是否为素数,如果是素数返回True,
    否则返回False'''
    if x < 2:
        return False
    # 走到此处时,x 一定大于等于2
    for i in range(2, x):
        if x % i == 0:  # 能整除就一定不是素数
            return False
    return True

1.
  L = list (filter(is_prime,range(100,200)))
  print(L)

2.
  s = sum(filter(is_prime,range(300,400)))
  print(s)

    sorted 函数

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

       # 示例:
            L = [5,-2,-4,0,3,1]
            L2 = sorted(L)  #[????]
            # 要得到这样的结果该怎么办?
            # [0,1,-2,-3,-4,-5]
            L3 = sorted(L,key=abs)

练习:
    已知:
        names = ['Tom','Jerry','Spike','Tyke']
        排序的依据为原字符串反序的字符串
        'moT','yrreJ','skipS','ekyT'
    结果:
        ['Spike', 'Tyke', 'Tom', 'Jerry']

1)
names = ['Tom','Jerry','Spike','Tyke']
def get_key(n):
    return n[::-1]
l = sorted(names,key=get_key)
print(l)

2) 
l = sorted(names,key=lambda n: n[::-1])

递归函数    recursion

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

#示例:
    def f():
        f()  调用自己,进入递归
    f()
    # 函数间接调用自身
    def fa():
        fb()
    def fb():
        fa()
    fa()
    print("递归完成")

    说明:
        递归一定要控制递归的层数,当符合一定条件时要终止递归调用
        几乎所有的递归都能用while循环来代替
    优点:
        递归可以把问题简单化,让思路更为清晰,代码更简洁
    缺点:
        递归因系统环境影响大,当递归深度太大时,可能会得到不可预知的结果

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

def fn(n):
    print('递归进入第',n,'层')
    if n == 3:
        return
    fn(n + 1)
    print('递归退出第',n,'层')
fn(1)
print('程序结束')

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


练习:
  写一个函数mysum(n),用递归方法求
  1 + 2 + 3 + 4 +...+ n 的和
  def mysum(n):
     ...
  print(mysum(100))  # 5050

def mysum(n):
    if n == 0: 
        return 0
    return n + mysum(n-1)
print(mysum(100))  # 5050

闭包  closure

    闭包是指引用了此函数外部嵌套函数作用域变量的函数

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

def make_power(y):
    def fn(x):
        return x ** y
    return fn

pow2 = make_power(2)
print('5的平方是:', pow2(5))

pow3 = make_power(3)
print("6的立方是", pow3(6))

# pow100 = make_power(100)
# print("2的100次方是:", pow100(2))

# 计算
 # 1** 2 + 2**2 + 3**2 + ..... + 9 ** 2
print(sum(map(lambda x: x**2, range(1, 9))))
print(sum(map(make_power(2), range(1, 9))))

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

def get_fx(a, b, c):
    def fx(x):
        return a*x**2 + b*x**1 + c
    return fx

# 创建函数 f(x) = 1*x**2 + 2*x**1 + 3
f123 = get_fx(1, 2, 3)
print(f123(20))  
print(f123(50))

f654 = get_fx(6,5,4)
print(f654(20))
print(f654(50))

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

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

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

#1
# 用递归来实同
# def get_age(n):
#     '''此函数返回第n个人多少岁'''
#     if n == 1:
#         return 10
#     return get_age(n - 1) + 2

# 用循环来实现
def get_age(n):
    '''此函数返回第n个人多少岁'''
    age = 10
    for _ in range(2, n + 1):
        age += 2
    return age

print('第五个人%d岁' % get_age(5))
#2.
L = [[3, 5, 8], 10, [[13, 14], 15, 18], 20]

# 1) 写一个函数print_list(lst)打印出列表内的所有元素
def print_list(lst):
    for x in lst:
        if type(x) is int:
            print(x, end=' ')
        else:
            print_list(x)  # 递归调用来处理内部的列表

print_list(L)  # 3 5 8 10 13 14...
print()


# 2) 写一个函数sum_list(lst): 返回这个列表中所有元素的和
def sum_list(lst):
    s = 0  # 用于累加lst中的所有数的和
    for x in lst:
        if type(x) is int:
            s += x
        else:
            s += sum_list(x)
    return s  # 返回当前的lst的结果def sum_list(lst):
    s = 0  # 用于累加lst中的所有数的和
    for x in lst:
        if type(x) is int:
            s += x
        else:
            s += sum_list(x)
    return s  # 返回当前的lst的结果

print(sum_list(L))  # 106

猜你喜欢

转载自blog.csdn.net/zh__quan/article/details/81839353