zoukankan      html  css  js  c++  java
  • part5-2 Python 函数高级(函数变量、函数参数、函数作为返回值,lambda 表达式),函数练习


    一、 函数高级内容


    Python 中的函数是“一等公民”,因此函数本身也是一个对象,函数即可用于赋值,也可用作其函数的参数,还可作为其他函数的返回值

    1、 使用函数变量
    Python的函数也是一种值。所有函数都是 function 对象,可以把函数本身赋值给变量,就像把整数、列表、元组等赋值给变量一样。把函数赋值给变量后,就可通过变量来调用函数。示例如下:
     1 def pow(base, exponent):
     2     """计算乘方"""
     3     result = 1
     4     for i in range(1, exponent + 1):
     5         result *= base
     6     return result
     7 my_fun = pow        # 将 pow 函数赋值给 my_fun 变量
     8 print(my_fun(3, 3))     # 计算3的3次方,输出:27
     9 
    10 def area(length, width):
    11     """计算面积"""
    12     return length * width
    13 my_fun = area       # 将 area 函数赋值给 my_fun 变量
    14 print(my_fun(4, 5))     # 计算面积,输出:20
    这里对 my_fun 变量赋值不同的函数,可以让 my_fun 在不同的时间指向不同的函数来让程序更加灵活。使用函数变量的好处是让程序更加灵活。

    2、 使用函数作为函数形参
    在函数中定义函数形参,这样可在调用该函数时传入不同的函数作为参数,从而动态改变这段代码。示例如下:
     1 def map(data, fn):
     2     """定义函数类型的形参,其中 fn 是一个函数"""
     3     result = []
     4     # 遍历 data 列表中的每个元素,并用 fn 函数对每个元素进行计算
     5     # 然后将计算结果作为新数组的元素
     6     for e in data:
     7         result.append(fn(e))
     8     return result
     9 # 定义一个计算平方的函数
    10 def square(n):
    11     return n * n
    12 # 定义一个计算立方的函数
    13 def cube(n):
    14     return n * n * n
    15 # 定义一个计算阶乘的函数
    16 def factorial(n):
    17     result = 1
    18     for i in range(2, n + 1):
    19         result *= i
    20     return result
    21 data = [2, 4, 6, 8, 10]
    22 print("列表原始数据:", data)
    23 print("计算列表元素的平方:")
    24 print(map(data, square))
    25 print("计算元素的立方:")
    26 print(map(data, cube))
    27 print("计算元素的阶乘:")
    28 print(map(data, factorial))
    29 print(type(map))
    30 
    31 运行程序输出如下:
    32 列表原始数据: [2, 4, 6, 8, 10]
    33 计算列表元素的平方:
    34 [4, 16, 36, 64, 100]
    35 计算元素的立方:
    36 [8, 64, 216, 512, 1000]
    37 计算元素的阶乘:
    38 [2, 24, 720, 40320, 3628800]
    39 <class 'function'>
    这里定义的 map() 函数的第二个参数是一个函数类型参数,这意味着每次调用函数时可以动态传入一个函数。传入不同的函数,可以动态改变 map() 函数中的部分计算代码。Python3 内置的 map 函数与这里定义的 map 函数功能相似,但是更强大。

    3、 使用函数作为返回值
    Python支持使用函数作为其他函数的返回值。示例如下:
     1 def foo(type):
     2     """定义一个函数,该函数包含局部函数"""
     3     def square(n):
     4         """定义一个计算平方的局部函数"""
     5         return n * n
     6     def cube(n):
     7         """定义一个计算立方的局部函数"""
     8         return n * n * n
     9     def factorial(n):
    10         """定义一个计算阶乘的局部函数"""
    11         result = 1
    12         for i in range(2, n + 1):
    13             result *= i
    14         return result
    15     # 调用局部函数
    16     if type == 'square':
    17         # 注意返回的函数不能加括号,只返回函数名称
    18         return square
    19     elif type == 'cube':
    20         return cube
    21     else:
    22         return factorial
    23 # 调用 foo 函数,程序返回一个嵌套函数
    24 cube = foo('cube')
    25 print(cube(10))             # 计算立方,输出:1000
    26 square = foo('square')
    27 print(square(5))            # 计算平方:输出:25
    28 factorial = foo('factorial')
    29 print(factorial(5))         # 计算阶乘:输出:120
    这次定义的 foo 函数体定义了3个局部函数,foo 函数由参数来决定返回哪一个函数。

    二、 局部函数与 lambda 表达式

    lambda 表达式是功能更灵活的代码块,可以在程序中被传递和调用。

    从前面的局部函数内容可知,局部函数的作用域仅在其封闭函数体内,离开这个封闭函数体,局部函数的函数名就失去了意义(当然可以用返回函数名的方法进行调用),可考虑用 lambda 表达式简化局部函数的写法。

    1、 使用 lambda 表达式代替局部函数
    使用 lambda 表达式简化前面的 foo 函数,代码如下:
     1 def foo(type):
     2     result = 1
     3     # 该函数返回的是 lambda 表达式
     4     if type == 'square':
     5         return lambda n: n * n
     6     elif type == 'cube':
     7         return lambda n: n * n * n
     8     else:
     9         return lambda n: (n + 1) * n / 2
    10 # 调用 foo 函数,程序返回的是一个嵌套函数
    11 square = foo('square')
    12 print(square(10))       # 计算平方,输出:100
    13 cube = foo('cube')
    14 print(cube(10))         # 计算立方,输出:1000
    15 other = foo('other')
    16 print(other(10))        # 求和,输出:55.0
    这次定义的 foo 函数体内,return 后面使用 lambda 关键字定义的是 lambda 表达式。Python 要求 lambda 表达只能是单行表达式,不允许使用复杂的函数形式。

    lambda 表达式的语法格式如下:
    lambda [参数列表]: 表达式

    lambda 表达式的几个要点:
    (1)、lambda 表达式必须使用 lambda 关键字定义。
    (2)、在 lambda 关键字之后、冒号左边的是参数列表,可以不给参数,也可以给多个参数。多个参数用逗号分隔,冒号右边是 lambda 表达的返回值。
    (3)、lambda 表达式也叫做匿名函数,也是单行函数体的函数。

    函数比 lambda 表达式的适应性更强,lambda 表达式只能创建简单的函数对象(适合函数体为单行的情形)。lambda表达的两个用途:
    (1)、对于单行函数,使用 lambda 表达式更简洁,省去定义函数的过程。
    (2)、对于不需要多次复用的函数,使用 lambda 表达式可以在用完之后立即释放,提高性能。

    下面示例使用内置的 map() 函数,参数是 lambda 表达式:
    1 # 计算平方
    2 x = map(lambda x: x * x, range(5))
    3 print([i for i in x])
    4 # 计算偶数的平方
    5 y = map(lambda x: x * x if x % 2 ==0 else 0, range(5))
    6 print([i for i in y])
    这段代码中 map 函数是内置函数,第一个参数是函数,第二个参数通常是列表、元组等。这里传入的 lambda 表达式,是简化的函数,这样程序更加简洁,性能也更好。

    三、 小结

    函数和lambda 表达式是 Python 编程的两大核心机制之一。Python 支持面向过程编程,也支持面向对象编程。函数和 lambda 表达式是面向过程编程的语法基础,需要重点掌握。

    要掌握函数的定义、函数调用语法,函数位置参数与关键字参数的区别和用法、形参默认值等特性。此外,函数也是一个 function 对象,函数可作为其他函数的参数,也可作为其它函数的返回值。把函数当成参数传入其他函数,可以让编程变得更加灵活。

    lambda 表达式是单行函数的简化版本,功能比较简单。

    练习:
    1、 定义一个函数,该函数可接收一个 list 作为参数,该函数使用直接选择排序对 list 排序。
     1 def choose_sort(sequence):
     2     length = len(sequence)
     3     for i in range(length):
     4         for j in range(i + 1, length):
     5             if sequence[i] > sequence[j]:
     6                 sequence[i], sequence[j] = sequence[j], sequence[i]
     7 
     8 seq = [100, 31, -50, 1, 3, 28,  -11, 85]
     9 choose_sort(seq)
    10 print(seq)      # 输出:[-50, -11, 1, 3, 28, 31, 85, 100]

    2、定义一个函数,该函数接收一个 list 作为参数,该函数使用冒泡排序对 list 排序。
    默认按升序排序,即从小到大排序。
    冒泡排序思路:首先,列表每两个相邻的数,如果前边的数比后边的数大,那么交换这两个数,第一次遍历完后,最大的这个数就在列表的末尾,接着第二次遍历,指针回到列表起始处,继续比较两个相邻的数,如果前边比后边大的,就交换这两个数,以此类推。
     1 def bubble_sort(sequence):
     2     length = len(sequence)
     3     for i in range(length):
     4         is_sorted = True     # 如果内层循环已经是从小到大的顺序,可通过判断这个变量来结束循环
     5         for j in range(length - i - 1):     # 减 1 是避免遍历到最后一个元素
     6             if sequence[j] > sequence[j + 1]:
     7                 sequence[j], sequence[j + 1] = sequence[j + 1], sequence[j]
     8                 is_sorted = False
     9         if is_sorted: return        # 如果内层循环已排序完成,就结束外层循环
    10 
    11 seq = [100, 31, -50, 1, 3, 28,  -11, 85]
    12 bubble_sort(seq)
    13 print(seq)      # 输出:[-50, -11, 1, 3, 28, 31, 85, 100]

    3、定义一个 is_leap(year) 函数,判断 year 是否为闰年。若是闰年则返回 True; 否则返回 False.
    闰年分为普通闰年和世纪闰年。普通闰年是指公历年份是4的倍数,例如2016年就是闰年。世纪闰年是指公历年份是整百数,必须是400的倍数才是闰年,例如1900年不是世纪闰年,2000是世纪闰年。
     1 def is_year(year):
     2     year = int(year)
     3     # 过滤整百数年份,判断普通闰年
     4     if (year % 4 == 0) and (year % 100 != 0):
     5         return True
     6     # 判断世纪闰年
     7     elif year % 400 == 0:
     8         return True
     9     else:
    10         return False
    11 
    12 while True:
    13     year = input("请输入年份:")
    14     if year == 'q' or year == 'exit':
    15         exit(0)
    16     else:
    17         print("%s是否是闰年?%s" % (year, is_year(year)))

    4、 定义一个 count_str_char(my_str) 函数,该函数返回参数字符串中包含多少个数字、多少个英文字母、多少个空白字符、多少个其它字符。
     1 def count_str_char(my_str):
     2     char_num, digit_num, space_num, other_num = 0, 0, 0, 0
     3     for s in my_str:
     4         if s.isdigit(): digit_num += 1
     5         elif s.isalpha(): char_num += 1
     6         elif s.isspace(): space_num += 1
     7         else: other_num += 1
     8     return char_num, digit_num, space_num, other_num
     9 
    10 while True:
    11     my_str = input("请输入一个字符串:")
    12     if my_str == 'q':
    13         exit()
    14     char_num, digit_num, space_num, other_num = count_str_char(my_str)
    15     print("字符个数是:", char_num)
    16     print("数字个数是:", digit_num)
    17     print("空白个数是:", space_num)
    18     print("其它字符个数是:", other_num)
    19     print("-" * 30)

    5、定义一个函数fn1(n),该函数返回 1到n 的立方和,即求:1+2*2*2+3*3*3+...+n*n*n
     1 def fn1(n):
     2     if n < 2:
     3         exit()
     4     result = 1
     5     for i in range(2, n + 1):
     6         result += i * i * i
     7     return result
     8 n = int(input("请输入一个数字:"))
     9 sum = fn1(n)
    10 print("1~%d的立方和是:%s" % (n, sum))

    6、定义一个fn2(n) 函数,该函数返回 n 的阶乘。
     1 def fn2(n):
     2     if n < 2:
     3         return 1
     4     result = 1
     5     for i in range(2, n + 1):
     6         result *= i
     7     return result
     8 
     9 def fn3(n):
    10     """用递归函数来实现阶乘"""
    11     if n <= 1:
    12         return 1
    13     else:
    14         return fn3(n - 1) * n
    15 
    16 def fn4(n):
    17     """用列表的方式计算阶乘"""
    18     if n <= 1:
    19         return 1
    20     my_list = [1]
    21     for _ in range(n):
    22         my_list.append(my_list[-1] * len(my_list))
    23     return my_list[-1]
    24 
    25 n = int(input("请输入一个整数:"))
    26 print("%d的阶乘是:%d" % (n, fn4(n)))

    7、定义一个函数,接收一个列表作为参数,函数用于去除列表中的重复元素。
     1 def no_repeat(sequence):
     2     my_list = []
     3     for s in sequence:
     4         if s not in my_list:
     5             my_list.append(s)
     6     return my_list
     7 
     8 def no_repeat_2rd(sequence):
     9     """利用字典的 fromkeys 方法,将列表的元素转换为字典的键,
    10     因字典的键不能重复,通过获取字典的键列表,就是去重后的列表"""
    11     my_list = list({}.fromkeys(sequence).keys())
    12     return my_list
    13 
    14 seq = ['a', 'java', 'c', 'python', 'c', 'stark', 'michael', 'c', 'a', 'python']
    15 print(no_repeat_2rd(seq))
    16 
    17 输出:
    18 ['a', 'java', 'c', 'python', 'stark', 'michael']

    8、定义一个函数 fn5(n) ,用于返回一个包含 n 个不重复的 0~100 之间整数的元组。
    注意:输入的整数大于100时,程序会陷入死循环。
     1 import random
     2 
     3 def fn5(n):
     4     i, my_list =0, []
     5     while True:
     6         temp_num = random.randint(0, 100)
     7         if temp_num not in my_list:
     8             my_list.append(temp_num)
     9             i += 1
    10         if i == n:
    11             break       # 结束循环
    12     return tuple(my_list)
    13 
    14 n = int(input("请输入一个整数:"))
    15 my_tuple = fn5(n)
    16 print("元组元素个数是:%d" % len(my_tuple))
    17 print(my_tuple)

    9、定义一个函数 fn6(n),该函数返回一个包含 n 个不重复的大写字母的元组。
     1 import random
     2 def fn6(n):
     3     i, my_list =0, []
     4     while True:
     5         num = random.randint(65, 90)
     6         s = chr(num)
     7         if s not in my_list:
     8             my_list.append(s)
     9             i += 1
    10         if i == n:
    11             break
    12     return tuple(my_list)
    13 
    14 n = int(input("请输入一个整数:"))
    15 print(fn6(n))

    10、定义一个函数 fn7(n),参数 n 表示一个 n 行 n 列的矩阵。在输出时,先输出 n 行 n 列的矩阵,再输出该矩阵的转置形式。例如参数是3时,先输出
    1 2 3
    4 5 6
    7 8 9
    再输出:
    1 4 7
    2 5 8
    3 6 9
     1 def fn7(n):
     2     # 输出矩阵
     3     for i in range(n):
     4         for j in range(n):
     5             print(" %2d " % (1 + j + i * n), end="")
     6         print()
     7     print("-" * (4 * n))
     8 
     9     # 输出转置矩阵
    10     for i in range(n):
    11         for j in range(n):
    12             print(" %2d " % (1 + i + j * n), end="")
    13         print()
    14 n = int(input("请输入整数:"))
    15 fn7(n)
  • 相关阅读:
    Android EditText内容监听
    Android模仿QQ空间图片上传——原理
    PHP新手入门1——表单
    linux下ftp常用命令
    TextView所有属性
    iOS开发-删除字典中的null
    去除导航栏下方的横线
    应用的启动视图 LauchView
    App所需申请资料
    应用本地化
  • 原文地址:https://www.cnblogs.com/Micro0623/p/11662214.html
Copyright © 2011-2022 走看看