一、lambda 匿名函数
lambda函数是一种匿名函数。它是一种快速定义单行函数的方法。与常规函数不同,lambda函数没有名称,也没有使用def关键字来定义。lambda函数通常用于一些简单的函数,可以在代码中快速定义和使用,而不需要为其定义一个正式的函数。
其中,arguments是函数的参数,可以有多个参数,用逗号分隔。expression是函数的表达式,它是函数的返回结果。例如:
add = lambda x, y: x + y
print(add(5, 3)) # 输出结果为8,其中5和3为参数,分别输给x和y
li = [1, 2, 3, 4]
new_li = []
f = lambda x: x + 1
print(f(1))
new_li = [f(i) for i in li]
print(new_li)
可分解为以下代码
li = [1, 2, 3, 4]
new_li = []
def summ(x):
x=x+1
return x
if __name__== "__main__":
summ(1)
print(summ(1))
new_li=[]
for i in li:
new_li.append(summ(i))
print(new_li)
优点:它们可以用于快速定义简单的函数,而不需要为其定义一个正式的函数。
缺点:它们的功能有限,只能包含一个表达式。如果需要在函数中包含多条语句或复杂的逻辑,就需要使用常规的函数定义。
二、映射函数(map)和规约函数(reduce)
map
和reduce
是Python中的两个常用高阶函数,用于对序列进行操作。
1、map:映射
函数接收一个函数和一个可迭代对象作为参数,将函数应用于可迭代对象的每个元素,并返回一个结果列表。它对序列中的每个元素应用同一个函数,并返回一个新的列表,列表中的每个元素是原列表中对应元素经过函数处理后的结果。例如:
numbers = [1, 2, 3, 4, 5]
squared_numbers = map(lambda x: x**2, numbers)
print(list(squared_numbers)) # 输出结果为 [1, 4, 9, 16, 25]
2、reduce:规约
函数接受一个函数和一个可迭代对象作为参数,将可迭代对象中的元素依次应用到函数上,得到一个结果。然后将该结果与下一个元素结合,再次应用函数,以此类推,直到遍历完可迭代对象,最终返回一个聚合结果。例如:
from functools import reduce
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(product) # 输出: 120
上部分代码,即通过匿名函数给予参数想,x,y的方法是x*y,然后通过规约函数赋予x,y的值为列表numbers中的元素,其工作方式为:x=1,y=2,然后x*y=1*2等于2,然后把这个2赋予给x,再把列表中的第三个数3赋予给y,继续进行x*y,等于2*3=6,然后再继续把6赋予给x,再把列表中的4赋予给y,继续进行x*y,直至结束。
三、命名空间namespace(局部、全局、内置)
命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的,其提供了在项目中避免名字冲突的一种方法。各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响。
1、局部:函数内部找变量
2、全局:在整个代码之前找变量
3、内置:Python内置的模块去寻找
例如在一个计算机系统中,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名
Python中一般有三种命名空间:
1、内置名称(built-in names):Python 语言内置的名称,比如函数名 abs、chr 和异常名称
BaseException、Exception 等等
2、全局名称(global names):模块中定义的名称,记录了模块的变量,包括函数、类、其
它导入的模块、模块级的变量和常量
3、局部名称(local names):函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量(类中定义的也是)
命名空间查找顺序:
假设我们要使用变量 money,则 Python 的查找顺序为:
局部的命名空间 -> 全局命名空间 -> 内置命名空间,如果找不到变量 money,它将放弃查找并引发一个错误
命名空间的生命周期:
命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束,因此无法从外部命名空间访问内部命名空间的对象
四、作用域(L、E、G、B)
在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
Python 的作用域一共有4种:
1、L(Local):局部作用域,包含局部变量,比如一个函数/方法内部
2、E(Enclosing):嵌套作用域,包含了非局部(non-local)也非全局(non-global)的变量
3、G(Global):全局作用域,最外层,比如当前模块的全局变量
4、B(Built-in):内置作用域,包含内建变量/关键字等,最后被搜索
在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问
1、全局作用域(Global scope):
在模块中定义的变量具有全局作用域,可以在模块的任何位置访问。
x = 10 # 全局作用域
def foo():
print(x) # 可以访问全局作用域中的变量
foo() # 输出: 10
2、局部作用域(Local scope):
在函数或类方法中定义的变量具有局部作用域,只能在定义它们的函数或方法内部访问。
def foo():
y = 20 # 局部作用域
def bar():
print(y) # 可以访问外部函数的变量
bar()
foo() # 输出: 20
3、嵌套作用域(Enclosing scope):
在嵌套函数中,内部函数可以访问外部函数的变量。
def outer():
z = 30 # 嵌套作用域
def inner():
print(z) # 可以访问外部函数的变量
inner()
outer() # 输出: 30
4、内置作用域(Built-in scope):
在Python解释器中预定义的变量和函数具有内置作用域,可以在任何地方访问。
print(len([1, 2, 3])) # 内置函数len()可以在任何地方访问
在Python中,变量的作用域遵循LEGB原则,即在访问变量时,首先在局部作用域查找,然后在嵌套作用域中查找,接着在全局作用域中查找,最后在内置作用域中查找。如果在任何作用域中都找不到变量,则抛出NameError异常。