【Python基础】函数

文章目录

  • 函数
    • 1 函数基础
      • 1.1 函数三要素与作用
      • 1.2 作用域
        • 1.2.1 LEGB原则
        • 1.2.3 命名空间
    • 2 匿名函数
      • 2.1 一个需求
      • 2.2 lambda
      • 2.3 匿名函数应用
        • 2.3.1 列表排序
        • 2.3.2 字典列表排序
    • 3 函数式编程
      • 3.1 map函数
      • 3.2 reduce函数
      • 3.3 fliter函数
    • 4 递归函数
      • 4.1 递归基本原理
      • 4.2 阶乘实现
      • 4.3 斐波那契数列
      • 4.4 遍历多维列表
    • 5 闭包
      • 5.1 基本概念
      • 5.2 闭包理解
      • 5.3 闭包使用场景
        • 5.3.1 n次幂计算
        • 5.3.2 闭包使用场景
        • 5.3.3 __closure__属性
    • 6 装饰器
      • 6.1 再看闭包
      • 6.2 使用装饰器
      • 6.3 wraps
    • 7 yield与生成函数
      • 7.1 带yeild关键字函数者;
      • 7.2 yield使用场景
      • 7.3 send方法

函数

1 函数基础

1.1 函数三要素与作用

  1. 函数名

    遵循规则:小写字母与下划线组成

def funcname(args):pass
  1. 函数参数

    参数类型:无参,有参,带默认值参数,可变长参数

# 无参函数
import time
def get_timestamp():return time.time()
get_timestamp()
1695367866.906982
# 形式参数
#1个参数函数
def str_to_int(s):if s.strip():return int(s.strip())return 0
#2个参数函数
def my_add(x, y):return x+ynum = str_to_int("10")
res = my_add(10, 20)
print(num, res)
10 30
# 带默认值参数
#默认十进制
def str_to_int(s, base = 10):value = int(s, base)return value
#十进制,逢十进一
base_10 = str_to_int("10")
#二进制,逢二进一
base_2 = str_to_int("10",base = 2)
print(base_10, base_2)
10 2
#位置参数与关键字参数
#定义求余函数
def calculate_remainder(m, n):return m%n
#位置参数
print(calculate_remainder(10,3))
#关键字参数
print(calculate_remainder(n = 3, m = 10))
1
1
# 可变长非关键字参数
print(min(1,2,3,5))
print(min(5,6,7))
1
5
def func(*args):print("*args value:", args)print("*args type :", type(args))print("*args拆包后:", *args)
func(1,2,3)
*args value: (1, 2, 3)
*args type : <class 'tuple'>
*args拆包后: 1 2 3
# 定义一个函数,分别求给定数据的最大值与最小值
def count_max_min(x, y, *args):max_val = max(x, y, *args)min_val = min(x, y, *args)print(max_val, min_val)listv = list(range(10))
#调用时拆包;
#调用时打包为元组;
count_max_min(1,2,*listv)
9 0
# 可变长关键字参数
#定义方式:
def func(**kwargs):print("**kwargs value:", kwargs)print("**kwargs type :", type(kwargs))print("*kwargs:", *kwargs)
#调用方式
func(name="sun", age=10)
**kwargs value: {'name': 'sun', 'age': 10}
**kwargs type : <class 'dict'>
*kwargs: name age
def test(**kwargs):func(**kwargs)dinfo = {"name":"sun", "age":10}
#调用test时候进行拆包为关键字参数
#执行中test将其打包成字典
test(**dinfo)
**kwargs value: {'name': 'sun', 'age': 10}
**kwargs type : <class 'dict'>
*kwargs: name age
#函数参数陷阱
#listv默认值列表
def test_func(value, listv = []):print(id(listv))listv.append(value)return listv
glist = []
v1 = test_func(1, glist)
v2 = test_func(2)
v3 = test_func(3)print(v1, id(v1))
print(v2, id(v2))
print(v3, id(v3))
2178159453632
2178159523200
2178159523200
[1] 2178159453632
[2, 3] 2178159523200
[2, 3] 2178159523200
  1. 函数返回值,默认返回None
#默认返回值
def func():pass
res = func()
print(res, type(res))
None <class 'NoneType'>
# return返回单个结果
def foo(x, y):return x+yres = foo(10, 20)
print(res)
30
# 返回多个对象
def count_max_min(x,y,*args):max_val = max(x, y, *args)min_val = min(x, y, *args)return max_val, min_valres = count_max_min(10, 20, 2,3,4,5)
print(res)
max_value, min_value = count_max_min(10, 20, 2,3,4,5)
print(max_value, min_value)
(20, 2)
20 2

1.2 作用域

作用域:变量在程序中的可应用范围

引入作用域操作:定义函数,类

1.2.1 LEGB原则
  1. L:Local——(函数内部)局部作用域

  2. E:Enclose——(嵌套函数的外层函数内部)嵌套作用域(闭包)

  3. G:Global——(模块全局)全局作用域

  4. B:Buildin ——(内建)内建作用域

Python查找变量的规则:LEGB;

Local-->Enclosed-->Global-->Builtin

x = 10
def func():x = 1print("in func x:", x)
func()
print("out func x:", x)
in func x: 1
out func x: 10
1.2.3 命名空间

命名空间(Namespace):实质名称到对象的映射,便于变量的查找;

局部命名空间(函数:local namespace):函数参数与局部变量

模块命名空间(全局:globalnamespace):全局变量,函数,导入模块等

内置命名空间(内置:build-in):内置函数及异常信息

x = 10000
def func():x = 1print("in func x:", x)print("locals:", locals())
func()
print("out func x:", x)
print("globals:", globals())
in func x: 1
locals: {'x': 1}
out func x: 10000
globals: {'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'def funcname(args):\n    pass', '# 无参函数\nimport time\ndef get_timestamp():\n    return time.time()\nget_timestamp()', '# 形式参数\n#1个参数函数\ndef str_to_int(s):\n    if s.strip():\n        return int(s.strip())\n    return 0\n#2个参数函数\ndef my_add(x, y):\n    return x+y\n\nnum = str_to_int("10")\nres = my_add(10, 20)\nprint(num, res)', '# 带默认值参数\n#默认十进制\ndef str_to_int(s, base = 10):\n    value = int(s, base)\n    return value\n#十进制,逢十进一\nbase_10 = str_to_int("10")\n#二进制,逢二进一\nbase_2 = str_to_int("10",base = 2)\nprint(base_10, base_2)', '#位置参数与关键字参数\n#定义求余函数\ndef calculate_remainder(m, n):\n    return m%n\n#位置参数\nprint(calculate_remainder(10,3))\n#关键字参数\nprint(calculate_remainder(n = 3, m = 10))', '# 可变长非关键字参数\nprint(min(1,2,3,5))\nprint(min(5,6,7))', 'def func(*args):\n    print("*args value:", args)\n    print("*args type :", type(args))\n    print("*args拆包后:", *args)\nfunc(1,2,3)', 'def count_max_min(x, y, *args):\n    max_val = max(x, y, *args)\n    min_val = min(x, y, *args)\n    print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', '# 定义一个函数,分别求给定数据的最大值与最小值\ndef count_max_min(x, y, *args):\n    max_val = max(x, y, *args)\n    min_val = min(x, y, *args)\n    print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', '# 可变长关键字参数\n#定义方式:\ndef func(**kwargs):\n    print("**kwargs value:", kwargs)\n    print("**kwargs type :", type(kwargs))\n    print("*kwargs:", *kwargs)\n#调用方式\nfunc(name="sun", age=10)', 'def test(**kwargs):\n    func(**kwargs)\n\ndinfo = {"name":"sun", "age":10}\n#调用test时候进行拆包为关键字参数\n#执行中test将其打包成字典\ntest(**dinfo)', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n    print(id(listv))\n    listv.append(value)\n    return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n    print(id(listv))\n    listv.append(value)\n    return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n    print(id(listv))\n    listv.append(value)\n    return listv\nglist = []\nv1 = test_func(1, glist)\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '#默认返回值\ndef func():\n    pass\nres = func()\nprint(res, type(res))', '# return返回单个结果\ndef foo(x, y):\n    return x+y\n\nres = foo(10, 20)\nprint(res)', '# 返回多个对象\ndef count_max_min(x,y,*args):\n    max_val = max(x, y, *args)\n    min_val = min(x, y, *args)\n    return max_val, min_val\n\nres = count_max_min(10, 20, 2,3,4,5)\nprint(res)\nmax_value, min_value = count_max_min(10, 20, 2,3,4,5)\nprint(max_value, min_value)', '### 1.2 作用域\n作用域:变量在程序中的可应用范围\n\n引入作用域操作:定义函数,类\n\n#### 1.2.1 LEGB原则\n1. L:Local——(函数内部)局部作用域\n\n2. E:Enclose——(嵌套函数的外层函数内部)嵌套作用域(闭包)\n\n3. G:Global——(模块全局)全局作用域\n\n4. B:Buildin ——(内建)内建作用域', 'x = 10\ndef func():\nx = 1\nprint("in func x:", x)\nfunc()\nprint("out func x:", x)', 'x = 10\ndef func():\n    x = 1\n    print("in func x:", x)\nfunc()\nprint("out func x:", x)', 'x = 10\ndef func():\n    x = 1\n    print("in func x:", x)\n    print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', 'x = 100000\ndef func():\n    x = 1\n    print("in func x:", x)\n    print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', 'x = 10000\ndef func():\n    x = 1\n    print("in func x:", x)\n    print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())'], '_oh': {2: 1695367866.906982}, '_dh': [WindowsPath('d:/study/code/jupyter/PythonLearning')], 'In': ['', 'def funcname(args):\n    pass', '# 无参函数\nimport time\ndef get_timestamp():\n    return time.time()\nget_timestamp()', '# 形式参数\n#1个参数函数\ndef str_to_int(s):\n    if s.strip():\n        return int(s.strip())\n    return 0\n#2个参数函数\ndef my_add(x, y):\n    return x+y\n\nnum = str_to_int("10")\nres = my_add(10, 20)\nprint(num, res)', '# 带默认值参数\n#默认十进制\ndef str_to_int(s, base = 10):\n    value = int(s, base)\n    return value\n#十进制,逢十进一\nbase_10 = str_to_int("10")\n#二进制,逢二进一\nbase_2 = str_to_int("10",base = 2)\nprint(base_10, base_2)', '#位置参数与关键字参数\n#定义求余函数\ndef calculate_remainder(m, n):\n    return m%n\n#位置参数\nprint(calculate_remainder(10,3))\n#关键字参数\nprint(calculate_remainder(n = 3, m = 10))', '# 可变长非关键字参数\nprint(min(1,2,3,5))\nprint(min(5,6,7))', 'def func(*args):\n    print("*args value:", args)\n    print("*args type :", type(args))\n    print("*args拆包后:", *args)\nfunc(1,2,3)', 'def count_max_min(x, y, *args):\n    max_val = max(x, y, *args)\n    min_val = min(x, y, *args)\n    print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', '# 定义一个函数,分别求给定数据的最大值与最小值\ndef count_max_min(x, y, *args):\n    max_val = max(x, y, *args)\n    min_val = min(x, y, *args)\n    print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', '# 可变长关键字参数\n#定义方式:\ndef func(**kwargs):\n    print("**kwargs value:", kwargs)\n    print("**kwargs type :", type(kwargs))\n    print("*kwargs:", *kwargs)\n#调用方式\nfunc(name="sun", age=10)', 'def test(**kwargs):\n    func(**kwargs)\n\ndinfo = {"name":"sun", "age":10}\n#调用test时候进行拆包为关键字参数\n#执行中test将其打包成字典\ntest(**dinfo)', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n    print(id(listv))\n    listv.append(value)\n    return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n    print(id(listv))\n    listv.append(value)\n    return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n    print(id(listv))\n    listv.append(value)\n    return listv\nglist = []\nv1 = test_func(1, glist)\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '#默认返回值\ndef func():\n    pass\nres = func()\nprint(res, type(res))', '# return返回单个结果\ndef foo(x, y):\n    return x+y\n\nres = foo(10, 20)\nprint(res)', '# 返回多个对象\ndef count_max_min(x,y,*args):\n    max_val = max(x, y, *args)\n    min_val = min(x, y, *args)\n    return max_val, min_val\n\nres = count_max_min(10, 20, 2,3,4,5)\nprint(res)\nmax_value, min_value = count_max_min(10, 20, 2,3,4,5)\nprint(max_value, min_value)', '### 1.2 作用域\n作用域:变量在程序中的可应用范围\n\n引入作用域操作:定义函数,类\n\n#### 1.2.1 LEGB原则\n1. L:Local——(函数内部)局部作用域\n\n2. E:Enclose——(嵌套函数的外层函数内部)嵌套作用域(闭包)\n\n3. G:Global——(模块全局)全局作用域\n\n4. B:Buildin ——(内建)内建作用域', 'x = 10\ndef func():\nx = 1\nprint("in func x:", x)\nfunc()\nprint("out func x:", x)', 'x = 10\ndef func():\n    x = 1\n    print("in func x:", x)\nfunc()\nprint("out func x:", x)', 'x = 10\ndef func():\n    x = 1\n    print("in func x:", x)\n    print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', 'x = 100000\ndef func():\n    x = 1\n    print("in func x:", x)\n    print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', 'x = 10000\ndef func():\n    x = 1\n    print("in func x:", x)\n    print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())'], 'Out': {2: 1695367866.906982}, 'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x000001FB246700D0>>, 'exit': <IPython.core.autocall.ZMQExitAutocall object at 0x000001FB24673850>, 'quit': <IPython.core.autocall.ZMQExitAutocall object at 0x000001FB24673850>, 'open': <function open at 0x000001FB22316AC0>, '_': 1695367866.906982, '__': '', '___': '', '__session__': 'd:\\study\\code\\jupyter\\PythonLearning\\Untitled.ipynb', '_i': 'x = 100000\ndef func():\n    x = 1\n    print("in func x:", x)\n    print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', '_ii': 'x = 10\ndef func():\n    x = 1\n    print("in func x:", x)\n    print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', '_iii': 'x = 10\ndef func():\n    x = 1\n    print("in func x:", x)\nfunc()\nprint("out func x:", x)', '_i1': 'def funcname(args):\n    pass', 'funcname': <function funcname at 0x000001FB24682340>, '_i2': '# 无参函数\nimport time\ndef get_timestamp():\n    return time.time()\nget_timestamp()', 'time': <module 'time' (built-in)>, 'get_timestamp': <function get_timestamp at 0x000001FB24682020>, '_2': 1695367866.906982, '_i3': '# 形式参数\n#1个参数函数\ndef str_to_int(s):\n    if s.strip():\n        return int(s.strip())\n    return 0\n#2个参数函数\ndef my_add(x, y):\n    return x+y\n\nnum = str_to_int("10")\nres = my_add(10, 20)\nprint(num, res)', 'str_to_int': <function str_to_int at 0x000001FB24682DE0>, 'my_add': <function my_add at 0x000001FB24681F80>, 'num': 10, 'res': (20, 2), '_i4': '# 带默认值参数\n#默认十进制\ndef str_to_int(s, base = 10):\n    value = int(s, base)\n    return value\n#十进制,逢十进一\nbase_10 = str_to_int("10")\n#二进制,逢二进一\nbase_2 = str_to_int("10",base = 2)\nprint(base_10, base_2)', 'base_10': 10, 'base_2': 2, '_i5': '#位置参数与关键字参数\n#定义求余函数\ndef calculate_remainder(m, n):\n    return m%n\n#位置参数\nprint(calculate_remainder(10,3))\n#关键字参数\nprint(calculate_remainder(n = 3, m = 10))', 'calculate_remainder': <function calculate_remainder at 0x000001FB24682C00>, '_i6': '# 可变长非关键字参数\nprint(min(1,2,3,5))\nprint(min(5,6,7))', '_i7': 'def func(*args):\n    print("*args value:", args)\n    print("*args type :", type(args))\n    print("*args拆包后:", *args)\nfunc(1,2,3)', 'func': <function func at 0x000001FB24683380>, '_i8': 'def count_max_min(x, y, *args):\n    max_val = max(x, y, *args)\n    min_val = min(x, y, *args)\n    print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', 'count_max_min': <function count_max_min at 0x000001FB24683060>, 'listv': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], '_i9': '# 定义一个函数,分别求给定数据的最大值与最小值\ndef count_max_min(x, y, *args):\n    max_val = max(x, y, *args)\n    min_val = min(x, y, *args)\n    print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', '_i10': '# 可变长关键字参数\n#定义方式:\ndef func(**kwargs):\n    print("**kwargs value:", kwargs)\n    print("**kwargs type :", type(kwargs))\n    print("*kwargs:", *kwargs)\n#调用方式\nfunc(name="sun", age=10)', '_i11': 'def test(**kwargs):\n    func(**kwargs)\n\ndinfo = {"name":"sun", "age":10}\n#调用test时候进行拆包为关键字参数\n#执行中test将其打包成字典\ntest(**dinfo)', 'test': <function test at 0x000001FB24682B60>, 'dinfo': {'name': 'sun', 'age': 10}, '_i12': '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n    print(id(listv))\n    listv.append(value)\n    return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))', 'test_func': <function test_func at 0x000001FB24682AC0>, 'glist': [1], 'v1': [1], 'v2': [2, 3], 'v3': [2, 3], '_i13': '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n    print(id(listv))\n    listv.append(value)\n    return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '_i14': '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n    print(id(listv))\n    listv.append(value)\n    return listv\nglist = []\nv1 = test_func(1, glist)\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '_i15': '#默认返回值\ndef func():\n    pass\nres = func()\nprint(res, type(res))', '_i16': '# return返回单个结果\ndef foo(x, y):\n    return x+y\n\nres = foo(10, 20)\nprint(res)', 'foo': <function foo at 0x000001FB24682A20>, '_i17': '# 返回多个对象\ndef count_max_min(x,y,*args):\n    max_val = max(x, y, *args)\n    min_val = min(x, y, *args)\n    return max_val, min_val\n\nres = count_max_min(10, 20, 2,3,4,5)\nprint(res)\nmax_value, min_value = count_max_min(10, 20, 2,3,4,5)\nprint(max_value, min_value)', 'max_value': 20, 'min_value': 2, '_i18': '### 1.2 作用域\n作用域:变量在程序中的可应用范围\n\n引入作用域操作:定义函数,类\n\n#### 1.2.1 LEGB原则\n1. L:Local——(函数内部)局部作用域\n\n2. E:Enclose——(嵌套函数的外层函数内部)嵌套作用域(闭包)\n\n3. G:Global——(模块全局)全局作用域\n\n4. B:Buildin ——(内建)内建作用域', '_i19': 'x = 10\ndef func():\nx = 1\nprint("in func x:", x)\nfunc()\nprint("out func x:", x)', '_i20': 'x = 10\ndef func():\n    x = 1\n    print("in func x:", x)\nfunc()\nprint("out func x:", x)', 'x': 10000, '_i21': 'x = 10\ndef func():\n    x = 1\n    print("in func x:", x)\n    print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', '_i22': 'x = 100000\ndef func():\n    x = 1\n    print("in func x:", x)\n    print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', '_i23': 'x = 10000\ndef func():\n    x = 1\n    print("in func x:", x)\n    print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())'}
#作用域陷阱
x = 10
def func():print(x)x = 20
func()
---------------------------------------------------------------------------UnboundLocalError                         Traceback (most recent call last)Cell In[24], line 64     print(x)5     x = 20
----> 6 func()Cell In[24], line 4, in func()3 def func():
----> 4     print(x)5     x = 20UnboundLocalError: cannot access local variable 'x' where it is not associated with a value
# global关键字
# 如何在局部变量中使用全局变量?x = 10
y = 10
def g_test():global xx = 20y = 30
g_test()
print("x=%d,y=%d"%(x, y))
x=20,y=10

2 匿名函数

2.1 一个需求

需求:判断一个数字是否是奇数,如果是奇数返回True,否则返回False

def is_odd(x):return x%2 == 1x = 10
print(f"{x} is odd:{is_odd(x)}")
x = 11
print(f"{x} is odd:{is_odd(x)}")
10 is odd:False
11 is odd:True

问题:这种简单的函效,能不能通过一条语句实现?

2.2 lambda

lambda;表示定义匿名函数,基本语法:

    #定义语法func = lambda:pass#调用方法func()

说明:

  1. lambda为关键字,在其他语言,例如:java中,也存在这种语法;
  2. 匿名函数没有名称,返回值为函数对象;
  3. 匿名函数中的表达式只能由一条语句;
  4. 匿名函数调用后返回值为表达式结果;
  5. 匿名函数不要太复杂,要考虑后期维护;
# 无参匿名函数
import time
get_ts = lambda:time.time()
get_ts()
1695371074.136779
# 带参数的匿名函数
'''
1. 计算两个数的和;
2. 给定一个成绩,判断是否及格(判断标准:大于等于60);
'''
x = 60
y = 50
my_add = lambda m, n: m + n
print(f"{x}+{y}= {my_add(x,y)}")
is_pass = lambda value:True if value >= 60 else False
print(f"{x} is pass:{is_pass(x)}")
print(f"{y} is pass:{is_pass(y)}")
60+50= 110
60 is pass:True
50 is pass:False
# 可变长参数匿名函数
my_sum = lambda x, y, *args: x + y + sum(args)
res = my_sum(1,2,3,4,5,6)
print(res)
21

2.3 匿名函数应用

2.3.1 列表排序

需求:给定数字列表.按照规则排序:每个元素与5的差的绝对值,从小到大排序;

nums = [-3, 2, 1,9,10]
nums.sort(key = lambda value:abs(5-value), reverse=False)
print(nums)
[2, 1, 9, 10, -3]
2.3.2 字典列表排序

给定一组用户信息,数据格式如下:

user_info = [{'name':'sun', 'age':10},{'name':'li', 'age':13},{'name':'zhao', 'age':12}]

需求:按照用户年龄从小到大排序

user_info = [{'name':'sun', 'age':15},{'name':'li', 'age':12},{'name':'zhao', 'age':13}]
user_info.sort(key=lambda item:item.get('age'))
user_info
[{'name': 'li', 'age': 12},{'name': 'zhao', 'age': 13},{'name': 'sun', 'age': 15}]

3 函数式编程

3.1 map函数

map(func, *iterables):对迭代对象每个元素处理,返回map对象

需求:

  1. 将字符串列表:['1', '2', '3']转成:[1,2,3]

  2. 给定三个学生语文与数学成绩,且一一对应:[90,80,40],[88, 92, 77,88],计算每个学生的总成绩;

  3. 某次消费记录:bill = ['Apple 20', 'Pear 5', 'Banana 10’] ,计算消费金额,结果为:35;

# 将字符串列表:['1', '2', '3']转成:[1,2,3]
l = ['1', '2', '3']
[int(val) for val in l]
[1, 2, 3]
r = map(int, l)
list(r)
[1, 2, 3]
# 给定三个学生语文与数学成绩,且一一对应:[90,80,40],[88, 92, 77,88],计算每个学生的总成绩;
math = [90,80,40]
chinese = [88, 92, 77,88]
res = map(lambda x, y, *args:x+y+sum(args), math, chinese)
list(res)
[178, 172, 117]
# 某次消费记录:bill = ['Apple 20', 'Pear 5', 'Banana 10'] ,计算消费金额,结果为:35;
bill = ['Apple 20', 'Pear 5', 'Banana 10']
res = sum(map(lambda val:int(val.split()[-1]), bill))
res
35
# 思考问题: 当调用map函数计算成绩时,是否发生了计算?def my_sum(x, y):print(f"{x}+{y}={x+y}")return x + y
math = [90,80,40]
chinese = [88, 92, 77,88]
#查看执行map结果
res = map(my_sum, math, chinese)
print(res)
res = list(res)
print(res)
<map object at 0x000001FB247F3E20>
90+88=178
80+92=172
40+77=117
[178, 172, 117]

3.2 reduce函数

reduce函数:

    from functools import reducereduce(function, sequence[, initial])

说明:

  1. function函数参数为2个;

  2. reduce调用过程:依次从sequence中取一个元素,和上一次function的结果做参数,再次调用function;

  3. 第一次调用function时,如果设置initial,function参数为:sequence的第一个元素和initial;

  4. 第一次调用function时,没有设置initial, function参数为:sequence中的前两个元素;

# 计算1~10的累加和;
from functools import reduce
res = reduce( lambda x, y: x+y, range(1, 11) )
print(f"sum res:", res)
#计算1~10阶乘
res = reduce( lambda x, y: x*y, range(1, 11) )
print(f"factorial res:", res)
sum res: 55
factorial res: 3628800
# 给定一组消费数据,计算累积销售额;
order_list = [{"数量":2, "单价":15},{"数量":1, "单价":10},{"数量":7, "单价":12},{"数量":4, "单价":13},]
def count_amount(value, order):amount = order.get("数量") * order.get("单价")return value + amountreduce(count_amount, order_list, 0)
176

3.3 fliter函数

filter函数用于根据条件过滤数据;

filter(function or None, iterable)

  1. filter作用:使用function对iterable每个元素进行处理, 将返回值为真的保留,返回filter迭代器;

  2. function为指定函数:处理iterable每个元素;

  3. function为None:根据iterable中的元素进行判断;

# 1. l = [1,2,3,4,5,6],过滤列表中的偶数;
l = [1,2,3,4,5,6]
res = filter(lambda val:val%2==0, l)
list(res)
[2, 4, 6]
# 2. report = [[90,80],[55,70],[50,45]],过滤成绩,平均分及格;
report = [[90,80],[55,70],[50,45]]
res = filter(lambda item:sum(item)/len(item) >=60, report)
list(res)
[[90, 80], [55, 70]]

4 递归函数

4.1 递归基本原理

递归函数:函数在内部调用自身;
递归函数特性:

  1. 函数内部,自己调用自己;

  2. 有一个明确的结束条件;

  3. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少;

  4. python中使用递归考虑

递归优缺点:

  1. 优点:逻辑简单清晰,

  2. 缺点:过深的调用会导致栈溢出;栈溢出

deep = 1
def func():global deepdeep += 1print("call func")func()
func()
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
...
call func
call func
call func
call funcRecursionError: maximum recursion depth exceeded while calling a Python object

栈溢出,递归报错!

deep
2973

4.2 阶乘实现

需求:计算N以内阶乘,1*2*3*....n

# 使用while循环
v = 1
i = 1
while i <=5:v *= ii+=1
print(v)
120
#递归实现
def recursion(num):print("num :", num)if num == 1:return numreturn num * recursion(num - 1)
recursion(5)
num : 5
num : 4
num : 3
num : 2
num : 1120

4.3 斐波那契数列

斐波那契数列:即著名的兔子数列:1、1、2、3、5、8、13、21、34、……

#输入n,计算对应的斐波那契数;
def fibo(n):if n <= 2:return 1else:return fibo(n-1) + fibo(n-2)for n in range(1, 10):print(fibo(n), end=" ")
1 1 2 3 5 8 13 21 34 

4.4 遍历多维列表

需求:遍历多维列表中的每个元素,注意:列表中子元素为:列表,单个字符,数字; 问题:

data = [1,2,3,['a', 'b', 'c',['d','e','f']],[4,5,6,[7,8,9]]]
def sort_list(items):for item in items:if isinstance(item, list):sort_list(item)else:print(item, end=" ")
sort_list(data)
1 2 3 a b c d e f 4 5 6 7 8 9 

5 闭包

5.1 基本概念

内部函数中,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)

# inner_fun是个闭包
def out_func(x):m = 10def inner_func(n):return n * m * xreturn inner_funcres = out_func(3)
res(2)
60

5.2 闭包理解

  1. 函数内部定义函数;

  2. 内部函数引用外部变量;

  3. 函数返回值为函数;

def foo():m = 10def bar(n):return n * mprint("id(bar):", id(bar))return bar
res = foo()
print(id(res))
print(res)
res(2)
id(bar): 2178159224096
2178159224096
<function foo.<locals>.bar at 0x000001FB24682520>20

在这个函数中,foo是外部函数,bar是内部函数,m是外部函数的局部变量,n是内部函数的参数。bar可以访问m和n,并返回它们的乘积。foo的返回值是bar的引用,也就是一个函数对象。当我们调用foo的时候,它会打印出bar的内存地址,并返回bar。当我们用foo的返回值去调用bar的时候,它会使用foo中的m和bar中的n进行计算,并返回结果。

func = foo()
func(2)
id(bar): 217817983756820

5.3 闭包使用场景

5.3.1 n次幂计算

需求:定义一组函数,计算指定数值N次幂

def make_pow2(n):return pow(n, 2)
def make_pow10(n):return pow(n, 10)
print("make_pow2(2)=",make_pow2(2))
print("make_pow10(2)=",make_pow10(2))
make_pow2(2)= 4
make_pow10(2)= 1024
# 传入参数可以为数字字符串,如何处理?
def make_pow2(n):return pow(int(n), 2)
def make_pow10(n):return pow(int(n), 10)
5.3.2 闭包使用场景
  1. 封装,代码复用;

  2. 装饰器;

# 可变长参数
def logfunc(level='info'):def logmsg(msg, *args, **kwargs):print(f'{level}--> : {msg}, {args},{kwargs}')return logmsgdebug_func = logfunc('debug')
info_func = logfunc('info')
error_func = logfunc('error')debug_func("test", 1,2,3, y=10)
info_func("info")
error_func("error")
debug--> : test, (1, 2, 3),{'y': 10}
info--> : info, (),{}
error--> : error, (),{}

可变长参数是指在调用函数时,传入的参数个数可以不固定。

Python支持两种可变长参数,分别是*args**kwargs,它们分别用来接收位置参数关键字参数

5.3.3 __closure__属性

__closure__是一个Python的属性,它用来表示一个函数对象是否是一个闭包函数。

__closure__属性的值是一个元组,它包含了所有被内部函数引用的外部函数的变量,这些变量被称为自由变量。每个自由变量都是一个cell类型的对象,它有一个cell_contents属性,用来存储变量的值。

# __closure__属性
def logfunc(level='info'):def logmsg(msg, *args, **kwargs):print(f'{level}--> : {msg}')return logmsginfo_func = logfunc('info')
print("info地址 :0x%016X"%id("info"))
info地址 :0x00007FFDEA00D400
info_func.__closure__
(<cell at 0x000001FADA79BA00: str object at 0x00007FFDEA00D400>,)
attr = info_func.__closure__
print("info地址 :0x%016X"%id("info"))
print("闭包closure:",type(attr), attr)
print("外部变量值 :",attr[0].cell_contents)
info地址 :0x00007FFDEA00D400
闭包closure: <class 'tuple'> (<cell at 0x000001FADA79BA00: str object at 0x00007FFDEA00D400>,)
外部变量值 : info

6 装饰器

装饰器:对函数进行处理,并返回新的函数

6.1 再看闭包

需求:定义一系列函数,对函数进行检验,前两个参数必须为整数;

def make_pow(x, y):print("call make_pow")if isinstance(x, int) and isinstance(y, int):return x ** y
def make_sum(x, y):print("call make_sum")if isinstance(x, int) and isinstance(y, int):return x + y
def make_mul(x, y):print("call make_mul")if isinstance(x, int) and isinstance(y, int):return x * y

问题:三个函数中检查参数重复,如果还要对其他参数进行检验,如何操作?

def deco_func(f):print("call deco_func")def inner(x, y, *args):print("call here inner")if isinstance(x, int) and isinstance(y, int):return f(x, y, *args)return innerdef make_pow(x, y, *args):print("call make_pow")return x ** ymake_new_pow = deco_func(make_pow)
call deco_func
make_new_pow(2,3,7)
call here inner
call make_pow8

6.2 使用装饰器

装饰器基本语法:

def deco_func(f):def inner():        return f(    return inner@deco_funcdef fo    ():pas注意:
1. deco_func为装饰器函数,2. foo被装饰函数,3. 当运行此代码,deco_func被调用,过程:foo = deco_func(foo),4. 结果:foo函数成为inner函数外部变量,foo指向inner函数s
#装饰器函数
def deco_func(f):print("call deco_func")def inner(x, y, *args):print("call here inner")if isinstance(x, int) and isinstance(y, int):return f(x, y, *args)return inner#被装饰函数
#@deco_func为装饰器语法糖:含义为make_pow=deco_func(make_pow)
@deco_func
def make_pow(x, y, *args):print("call make_pow")return x ** y
call deco_func
make_pow(2,3)
call here inner
call make_pow8

问题:如何在输出信息中添加:info, debug, error;

解决方式:将deco_func修改为内部变量,在外添加level_func

def level_func(level):def deco_func(f):def inner(msg):'''inner lever'''msg = level + " msg:"+msgf(msg)return innerreturn deco_func
#调用过程
#1:调用level_func,返回deco_func, 
#2:@deco_func对log_info进行装饰,返回inner
@level_func("info")
def log_info(msg):'''info level'''print(msg)@level_func("error")
def log_error(msg):'''error level'''print(msg)log_info("this is test")
log_error("this is test")
info msg:this is test
error msg:this is test
log_error?
[1;31mSignature:[0m [0mlog_error[0m[1;33m([0m[0mmsg[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m
[1;31mDocstring:[0m inner lever
[1;31mFile:[0m      c:\users\26822\appdata\local\temp\ipykernel_17220\3799119143.py
[1;31mType:[0m      function

6.3 wraps

装饰器使用问题:某些场景下,我们希望使用装饰器,但是,不希望改变函数名及说明,例如:

from functools import wraps
def deco_func(f):#使用wraps装饰f@wraps(f)def bar():'this bar func'f()return bar@deco_func
def test():'this is test func, do nothing'passtest?
[1;31mSignature:[0m [0mtest[0m[1;33m([0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m
[1;31mDocstring:[0m this is test func, do nothing
[1;31mFile:[0m      c:\users\26822\appdata\local\temp\ipykernel_17220\1862026155.py
[1;31mType:[0m      function

7 yield与生成函数

主要内容

  1. yield;

  2. 生成器函数应用;

  3. 基于yield实现生产者与消费

7.1 带yeild关键字函数者;

def func():print("--> step 1")yield "hello"print("--> step 2")yield "world"print("--> step 3")
gen = func()
gen
<generator object func at 0x000001FADA703AC0>
next(gen)
--> step 1'hello'
next(gen)
--> step 2'world'
next(gen)
--> step 3---------------------------------------------------------------------------StopIteration                             Traceback (most recent call last)Cell In[29], line 1
----> 1 next(gen)StopIteration: 

调用说明:

  1. func被调用,并不会执行;
  2. func被调用后返回生成器;
  3. 可以使用next函数或者for对生成器操作;

yield的调用过程:

  1. 第一次调用next(gen)执行后,遇到yield关键字,返回其对应的对象,并保存现场;
  2. 再次调用next(gen),从yield的下一条语句继续执行;
  3. 重复1~2,如果执行完成,触发StopIteration异常;

7.2 yield使用场景

需求:

  1. 生成随机数池,可以无限取值,范围:[1, 9999];

  2. 使用yield完成斐波那契数列;

# 随机数池
import random
def random_pool(min_val, max_val):while True:yield random.randint(min_val, max_val) 
random_gen = random_pool(1, 9999)
next(random_gen)
6363
#斐波那契数列
def fibo(n):a,b = 0, 1i = 1while i < n:i += 1yield ba, b = b, a+b
gen_fibo = fibo(10)
for val in gen_fibo:print(val)
1
1
2
3
5
8
13
21
34

7.3 send方法

生成器函数可以传参并接受参数

  1. 生成器对象调用send方法传参;

  2. 生成器函数 value = yield obj接受参数

需求:定义生成器函数,将字符串数字转成整数,若转化值为"q",退出;;

def custom():value = yield ''while value != 'q':value = yield int(value)*10
gen = custom()
next(gen)
''
gen.send('20')
200
gen.send('q')
---------------------------------------------------------------------------StopIteration                             Traceback (most recent call last)Cell In[40], line 1
----> 1 gen.send('q')StopIteration: 

调用过程:

  1. 使用next方法,启动生成器,生成器返回"",保留现场,等待下一次调用;

  2. 调用生成器send方法,传入参数,value接受参数,执行到yield返回并保存现场;

  3. 重复1~2过程,如果遇到"q",退出;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/667958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【stm32】hal库学习笔记-ADC模数转换(超详细!)

【stm32】hal库学习笔记-ADC模数转换&#xff08;超详细&#xff01;&#xff09; 本篇章介绍了ADC实现电压检测的三种方式 ADC原理及选型 ADC将连续的模拟电压信号转换为二进制的数字信号 选型参数 速度&#xff08;采样频率&#xff09; 功耗 精度 转换原理 ADC hal库驱…

Linux进程信号(2)--信号的保存

目录 1.阻塞信号 1.1 信号其他相关常见概念 1.实际执行信号的处理动作称为信号递达(Delivery&#xff09; 2.信号从产生到递达之间的状态,称为信号未决(Pending)。 3.进程可以选择阻塞 (Block )某个信号。 1.2信号在内核中的表示 sigset_t 信号集操作函数 使用sigprocm…

安全基础~通用漏洞4

文章目录 知识补充XSS跨站脚本**原理****攻击类型**XSS-后台植入Cookie&表单劫持XSS-Flash钓鱼配合MSF捆绑上线ctfshow XSS靶场练习 知识补充 SQL注入小迪讲解 文件上传小迪讲解 文件上传中间件解析 XSS跨站脚本 xss平台&#xff1a; https://xss.pt/ 原理 恶意攻击者…

802.11n 802.11ac (WiFi 4/5 )的核心要点

802.11n 802.11ac &#xff08;WiFi 4/5 &#xff09;是什么&#xff1f; WiFi 4&#xff1a; Ieee 802.11n Enhancements for High Throughput &#xff08;HT&#xff09; WiFi 5&#xff1a; Ieee 802.11ac Enhancements for Very High Throughput &#xff08;VHT&#x…

kerberos 生成新用户和 keytab 文件

操作很简单 kadmin.localkadmin.local: ktadd -k /root/test1.keytab -norandkey test1登录认证中心 kadmin.local增加用户 kadmin.local: addprinc -pw ****** test1生成 keytab 文件 kadmin.local: ktadd -k /root/test1.keytab -norandkey test1退出认证中心上下文。…

4.0 HDFS 配置与使用

之前提到过的 Hadoop 三种模式&#xff1a;单机模式、伪集群模式和集群模式。 单机模式&#xff1a;Hadoop 仅作为库存在&#xff0c;可以在单计算机上执行 MapReduce 任务&#xff0c;仅用于开发者搭建学习和试验环境。 伪集群模式&#xff1a;此模式 Hadoop 将以守护进程的…

vue如何在页面创建一个客服对话框

Vue可以通过使用组件来创建一个客服对话框。下面是一种常见的实现方式&#xff1a; 首先&#xff0c;我们需要定义一个名为"CustomerServiceDialog"的组件&#xff0c;该组件将作为客服对话框显示在页面上。 <template><div class"customer-service-d…

编程思维与生活琐事的内在关联及其应用价值

随着科技的日益普及和信息化时代的到来&#xff0c;编程作为一种现代技能&#xff0c;其影响已不再局限于专业领域&#xff0c;而是逐步渗透到人们的日常生活之中。探讨编程与生活琐事之间的关系&#xff0c;有助于我们更好地理解如何将技术智慧应用于日常管理&#xff0c;提升…

MacOS Mojavev10.14.6

MacOS Mojave v10.14.6系统安装包是一款专为Mac用户设计的操作系统软件包。Mojave是苹果公司为Mac设备开发的一个操作系统版本&#xff0c;它提供了许多新功能和改进&#xff0c;旨在提高Mac用户的使用体验和工作效率。 安装MacOS Mojave v10.14.6系统后&#xff0c;用户可以享…

洛谷 P1359 租用游艇

题目描述 长江游艇俱乐部在长江上设置了 n 个游艇出租站 1,2,⋯,n。游客可在这些游艇出租站租用游艇&#xff0c;并在下游的任何一个游艇出租站归还游艇。游艇出租站 i 到游艇出租站 j 之间的租金为 r(i,j)&#xff08;1≤i<j≤n&#xff09;。试设计一个算法&#xff0c;计…

蓝桥杯Web应用开发-display属性

display 属性 专栏持续更新中 display 属性可以用来设置元素在页面上的排列方式&#xff0c;也可用来隐藏元素。 display 属性值的说明如下表所示。 属性值说明block元素以块级方式展示。inline元素以内联方式展示。inline-block元素以内联块的方式展示。none隐藏元素。 b…

微信小程序之本地生活案例的实现

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

算法学习——华为机考题库8(HJ46 - HJ55)

算法学习——华为机考题库8&#xff08;HJ46 - HJ50&#xff09; HJ46 截取字符串 描述 输入一个字符串和一个整数 k &#xff0c;截取字符串的前k个字符并输出 数据范围&#xff1a; 字符串长度满足 1≤n≤1000 &#xff0c; 1≤k≤n 输入描述&#xff1a; 1.输入待截取的…

代码随想录算法训练营Day24 | 回溯理论基础、77.组合

回溯理论基础 回溯和递归是相辅相成的&#xff0c;只要有递归就有回溯&#xff08;执行完一次递归就自动回溯到上一层&#xff09; 回溯的效率 回溯不是一个高效的算法&#xff0c;而是一个纯暴力的过程 有些问题没有更好的解法&#xff0c;只能使用暴力搜索&#xff0c;这时…

【LeetCode每日一题】2381. 字母移位 II2406. 将区间分为最少组数 (差分数组)

差分数组案例 2381. 字母移位 II 给你一个小写英文字母组成的字符串 s 和一个二维整数数组 shifts &#xff0c;其中 shifts[i] [starti, endi, directioni] 。对于每个 i &#xff0c;将 s 中从下标 starti 到下标 endi &#xff08;两者都包含&#xff09;所有字符都进行移…

ReactNative实现的横向滑动条

OK&#xff0c;我们先看下效果图 注意使用到了两个库 1.react-native-linear-gradient 2.react-native-gesture-handler ok&#xff0c;我们看下面的代码 import {Image, TouchableWithoutFeedback, StyleSheet, View} from react-native; import LinearGradient from reac…

Linux---信号

前言 到饭点了&#xff0c;我点了一份外卖&#xff0c;然后又开了一把网游&#xff0c;这个时候&#xff0c;我在打游戏的过程中&#xff0c;我始终记得外卖小哥会随时给我打电话&#xff0c;通知我我去取外卖&#xff0c;这个时候游戏还没有结束。我在打游戏的过程中需要把外…

Docker 第十二章 : Docker 三剑客之 Swarm (节点管理命令)

第十二章 : Docker 三剑客之 Swarm (节点管理命令) 本章知识点: 本文介绍了Docker三剑客之Swarm的节点管理与命令。Swarm是Docker集群管理工具,允许用户轻松部署和管理容器化的应用程序。通过节点管理和命令,用户可以配置Swarm集群,包括添加、删除和更新节点,以及执行…

考研中常见的算法-逆置

元素逆置 概述&#xff1a;其实就是将 第一个元素和最后一个元素交换&#xff0c;第二个元素和倒数第二个元素交换&#xff0c;依次到中间位置。用途&#xff1a;可用于数组的移动&#xff0c;字符串反转&#xff0c;链表反转操作&#xff0c;栈和队列反转等操作。 逆置图解 …

<网络安全>《16 网络安全隔离与信息单向导入系统》

1 概念 网络安全隔离与信息单向导入系统解决了从外网向内网、低密级环境向高密级环境单向传输数据的问题。系统利用光单向传输的特性构建了一条安全、单向的传输通道&#xff0c;实现了外网到内网的数据传输&#xff08;低密级到高密级的传输&#xff09;&#xff0c;又能完全…