函数
在python中,函数也是对象。
def func():
"""
这是文档字符串
"""
print("Hello World")
fun
带参数函数
函数和变量注解
def calc(a:int, b:int) -> int: # 为函数的形参和返回值标注类型
return a + b
print(calc(1,34))
传递实参的方式
- 位置参数
- 关键字参数
def func(a,b = 34):
return a + b
print(func(b = 3, a = 3)) # 按关键字参数传入,不强求顺序
print(func(3,33)) # 按位置参数传入,要求顺序
print(func(3))
仅位置参数与仅关键字参数
def func(a,b, /, c,d, *, e,f): # / 之前的参数为仅位置参数,* 之后的参数为仅关键字参数
"""
a,b只能使用位置参数传入
e,f只能使用关键字参数传入
c,d任意
"""
print(a,b,c,d,e,f)
func(1,2,c = 3, d = 34,e = 1, f = 34)
参数解包
def func(a,*b,**c): # 参数解包 * 序列解包为位置参数,** 字典解包为关键字参数
print(a,b,c)
func(1,3,3,3,3,3,3,3, k = "dkfj")
参数传递
a = [1,2,3]
def func(p):
p.append(3)
func(a)
print(a)
变量的命名空间
与其他编程语言相同(
a = 3
def func():
a = 38
print(a)
func()
print(a)
a = 3
def func():
global a
a = 38
print(a)
func()
print(a)
匿名函数
与C++的lambda表达式类似
f = lambda x: x ** 2
print(f(3))
闭包
def func():
l = []
def inner(a):
l.append(a) # l 是外层命名空间变量
return sum(l) / len(l) # 计算列表l平均值
return inner # 函数作为返回值,且使用了外层命名空间的变量l
avg = func()
print(avg(1))
print(avg(2))
print(avg(3))
在python中,函数也是对象,类似于avg是一个对象,内置了一个列表。
类似于这个函数:
def func(a, b = []):
b.append(a)
return sum(b) / len(b)
print(func(1))
print(func(2))
print(func(3))
装饰器
Python中的装饰器是用来修改或者增强函数或者类的行为的。装饰器可以在不修改被装饰对象源代码的情况下,对其进行功能的扩展或者包装。
装饰器实际上是一个高阶函数,它接受一个函数(或者类)作为参数,然后返回一个新的函数(或者类)。
def decorator(func):
def wrapper(*args):
print(f"Calling function: {func.__name__}")
return func(*args)
return wrapper
@decorator
def add(a,b):
return a + b
print(add(3,4))
解释一下具体的执行过程:
@decorator
语法将decorator
装饰器应用在add
函数上,相当于执行add = decorator(add)
- 调用
add(3, 4)
时,实际上是调用了经过装饰后的wrapper
函数,并传入参数(3, 4)
wrapper
函数内部首先打印函数名Calling function: add
- 然后调用原始的
add
函数,并将参数(3, 4)
传递给它 add
函数执行完毕后,wrapper
函数返回原始add
函数的返回值,即7
- 最终,
7
被打印出来
这样,通过装饰器,在函数执行前添加了额外的功能,即打印函数名。
注意,装饰器可以叠加使用,一个函数可以同时应用多个装饰器,装饰器的执行顺序是从上到下的。
迭代器和生成器
迭代器
迭代器是一个可迭代对象(Iterable),它定义了一个 __next__
方法,每次调用这个方法都会返回序列中的下一个元素。当没有更多元素时,__next__
方法抛出 StopIteration
异常。
可以使用 iter()
函数将一个可迭代对象转换成迭代器。例如:
a = [1,2,3]
it = iter(a)
print(next(it))
print(next(it))
print(next(it))
生成器
生成器是一种特殊类型的迭代器,它可以通过函数来创建。生成器函数使用 yield
语句来产生一个值,并且暂停执行函数,直到下一次请求产生值。当函数执行完毕时,自动抛出 StopIteration
异常。
def func():
yield 1
yield 2
yield 3
a = func()
print(list(a))
打印斐波那契数列
def fib(n: int) -> int:
i,a,b = 0,0,1
while i < n:
yield b
a, b = b, a + b
i += 1
print(list(fib(10)))
生成器推导式
注意:不是元组推导式,元组是不可变类型
print(list( (x ** 2 for x in range(10))))
常用内置序列函数和高阶函数
排序
sort()
是在原来数据上直接进行排序,返回值是None,sorted()
是返回原来数据的排序结果,不在原数据上排序。
l = [2,3,1,34,4]
l.sort()
print(l)
l = [2,3,1,34,4]
k = sorted(l)
print(k,l)
排序默认是按照从小到大的结果进行排序的,如果想要从大到小进行排序,进行翻转就行。
l = [2,3,1,34,4]
l.sort(reverse=True)
print(l)
多维列表排序
结合匿名函数。
l = [
[1,3],
[34,34],
[3434,1],
[2,3434]
]
l.sort(key=lambda x: (-x[0], x[1])) # 第一位是降序,第二位升序
print(l)
翻转
操作同排序。reverse()
是在原来数据上进行的翻转,更改了原来数据;而reversed()
则是返回一个翻转后的内容的迭代器,对原来数据不进行翻转。
l = [2,3,1,34,4]
l.reverse()
print(l)
l = [2,3,1,34,4]
k = reversed(l)
print([*k],l)
enumerate
返回可迭代对象的枚举对象
l = ['a', 'b', 'c', 'd']
for idx, val in enumerate(l):
print(idx, val)
zip
创建一个zip对象,聚合来自每个可迭代对象中的元素
zip对象是一种元组生成器,第i个元组包含来自每个可迭代对象的第i个元素
print(list(zip([1,2], ['a', 'b'])))
map
将函数作用到可迭代对象的每一项上,返回map对象,也是一种生成器。
算法竞赛中读入数据,将读入的字符串用空格进行切割,之后用int函数,转为int整数型。
print(list(map(int, input().split(' '))))