Python进阶
函数的定义和调用
函数定义通常采用def
关键词,后面跟着函数名及圆括号内的参数列表。
def function_name (parameters):
"""函数文档字符串"""
# 函数体
...
return expression # 可选,用于返回函数结果
function_name
是函数名,应满足Python的标识符命名规则。parameters
是传递给函数的变量名,多个参数之间用,
分割,参数可以设置默认值。- 函数文档字符串,是位于函数定义内部第一行的一对三引号包围的字符串,用于描述函数的功能、输入输出等信息,有助于编写文档和调试。
- 函数体内包含了函数需要执行的所有操作。
retrun
语句用于结束函数的执行并返回一个值给调用者,如果没有return
,或者return
语句后没有表达式,则默认返回None
。
函数定义
# 定义一个greet函数,接受一个必传参数name,两个可选参数greeting, punctuation
def greet(name, greeting = 'Hello', punctuation = '!'):
"""打招呼"""
return f"{name},{greeting}{punctuation}"
函数调用
print(greet('小明')) # 使用默认值打招呼
print(greet('小明', 'Hi')) # 覆盖greeting传参的默认值
print(greet('小明', 'Hi', '?')) # 提供所有参数的值
Python中,除默认值参数之外(如上面的greet
参数),函数的每个参数都是必传的,否则回出现语法错误。
- 必选参数(位置参数),在函数定义时没有提供默认值的参数被视为必选参数,必须按照它们在函数定义时的顺序提供相应实参,否则回导致语法错误。
def my_func(required_arg1, required_arg2):
pass
调用时
# 必须这样调用,缺少任何一个参数会引发TypeError
my_func(value1, value2)
- 关键词参数,通过key=value的形式指定参数名来传入参数,关键词参数允许调用时忽略参数的顺序,只要参数名与函数定义的形参名一致即可。
def func(a, b, c):
pass
调用
func(c=3, a=1, b=2)
- 混合使用位置参数和关键词参数
-
- 位置参数必须出现在关键词参数之前。
-
- 如果函数定义中有默认值的参数(即默认参数),则在没有指定关键词的情况下,后面的所有参数都必须作为关键词参数传递。
def func(required1, required2, default = None):
pass
# 混合使用位置参数和关键词参数
func(1, 2, default = 3) # required1 = 1, required2 = 2, default = 3
*args
和 **kwargs
是两种特殊语法,用于函数定义时收集不确定数量的参数。
*args
用于接收任意数量的位置参数,并将它们以元组(tuple
)的形式存储。当不确定回传递多少个位置参数时,可以使用。
def my_function(*args):
print(type(args)) #<class 'tuple'>
for arg in args:
print(arg)
my_function(1, 2, 3, 'four')
**kwargs
:用于接收任何数量的关键词参数,并将它们以字典(dict
)的形式存储。当你不确定会传递多少个关键词参数给函数时,可以使用**kwargs
def my_function(**kwargs):
print(typpe(kwargs)) # <class 'dict'>
for key, value in kwargs.items()
print(f"{key}:{value}")
my_function(a=1, b=2, c='three')
同时使用
def my_function(*args, **kwargs):
print(args) # 输出位置参数组成的元组 (1, 2, 3)
print(kwargs) # 输出关键字参数组成的字典 {'a': 4, 'b': 5}
my_function(1, 2, 3, a=4, b=5)
经典高阶函数
map()
- 接收一个函数和一个或多个序列作为参数。
- 将函数依次应用到各个序列的所有元素上,返回一个可迭代对象。
示例:list(map(func, iterable)),将func函数应用到iterable中的每个元素上。
map()经典案例一
- 计算列表中所有整数的平方
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(lambda x: x**2, numbers))
print(squared_numbers) # [1, 4, 9, 16, 25]
这里拓展lambda
lambda
是python中的一种特殊语法,用于创建匿名函数。这种函数没有名称,仅用于临时使用,常常出现在需要一次性定义简单功能的地方,比如作为高阶函数(map,filter,sorted)的参数。
lambda arguments: expression
arguments
是你传递给函数的参数,可以又一个或者多个,多个参数之间用逗号分隔。
expression
是函数体,是一个单行表达式,该表达式的计算结果就是函数的返回值。
普通函数定义:
def square(x):
return x * x
使用lambda表达式:
square = lambda x : x * x
这里拓展list()
关于list()
,在python3中,map()
函数返回的是一个可迭代的映射对象(map object
),而不是列表,为了能够进一步直接查看或进一步处理转换后的结果,通常需要将其转换为列表或者其他序列类型。
以下示例会演示,如果不使用list()
进行转换,仍然可以迭代map
对象,但不能直接查看内容或者调用列表特有方法。
words = ['hello', 'world', 'python']
uppercased_word_map = map(str.upper, words)
# 直接打印
print(uppercased_word_map) 输出 <map object at ox7f8c1...>
# 迭代map对象
for word in uppercased_word_map:
print(word) # HELLO WORDLE PYTHON
# 如果将其转换为列表
uppercased_words_list = list(uppercased_word_map)
print(uppercased_words_list) # ['HELLO', 'WORDLE', 'PYTHON']
也可以用lambda
函数来代替str.upper
方法,但没必要这样做,因为str.upper
已经是一个现成的函数,可以直接用于map()
函数。
words = ['hello', 'world', 'python']
uppercased_words = list(map(lambda x: x.upper, words))
print(uppercased_word) # ['HELLO', 'WORLD', 'PYTHON']
- 合并两个列表的对应元素
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
combined = list(map(lambda x, y: (x, y), list1, list2))
print(combined) # [(1, 'a'), (2, 'b'), (3, 'c')]
filter()
- 接收一个函数和一个序列作为参数。
- 根据函数对序列的每个元素进行测试,只保留函数返回值为
True
的元素,返回一个包含这些元素的新迭代器或者列表 - 示例:list(filter(pred, iterable)), 筛选出iterable中pred(element)为True的元素。
迭代器(Iterator)是编程中一种重要的设计模式和抽象概念,它提供了一种统一且高效的方式来遍历任何支持迭代的数据结构(如列表、集合、字典、文件、生成器等),而无需了解这些数据结构的内部实现细节。
filter()经典案例一
- 筛选出偶数
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
evens_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(evens_numbers) # [2, 4, 6, 8]
拓展列表list()
# 列表推导公式
evens_numbers3 = [x for x in evens_numbers if x % 2 == 0]
在这段示例中,filter
函数接收一个lambda
函数作为条件,该函数检查每一个元素是否能够被2整除,filter()
返回一个包含所有偶数的迭代器,然后用list()
将其转换为列表。
- 筛选出字符串列表中长度大于3的字符串
words = ["apple", "banana", "cheery", "cat"]
long_words = list(filter(lambda x: len(x) > 3, words))
print(long_words) # ['apple', 'banana', 'cheery']
filter()
函数中使用一个lambda
匿名函数来检查列表中每个字符串的长度是否大于3
, 满足条件的字符串会被包含在返回的新迭代器中,再转换成列表。
- 检查一个整数是否为质数
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n*0.5) + 1):
if n % i == 0:
return False
return True
primes = list(filter(is_prime, numbers)) # 输出:[2, 3, 5, 7]
reduce()
reduce()
是一个高阶函数,主要作用是对一个可迭代对象(如列表、元组、集合等)中的元素应用一个二元函数(接收两个参数的函数),累计计算所有元素,并最终返回一个单一的累计结果。reduce()
的经典示例包括求和,乘积、最大值、最小值、字符串拼接等。
- 求和
from functools import reduce # 在 Python 3 中需要导入 functools
numbers = [1, 2, 3, 4, 5]
sum_result = reduce(lambda x, y: x + y, numbers)
print(sum_result)
在这个例子中,reduce()
使用一个匿名函数(lambda
表达式)作为累加器,该函数接受两个参数 x
和 y
,并返回它们的和。reduce()
将此函数应用于 numbers
列表的所有元素,从左到右依次计算:
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
10 + 5 = 15
- 字符串拼接
from functools import reduce
strings = ['Hello', '', 'World', '!']
concat_result = reduce(lambda x, y: x + y, strings)
print(concat_result) # 输出:Hello world!
这里,reduce()
使用一个类似的过程,但累加器函数是将两个字符串连接起来。reduce()
将字符串列表中的元素逐一拼接:
"Hello" + " " = "Hello "
"Hello " + "world" = "Hello world"
"Hello world" + "!" = "Hello world!"
- 最大值
numbers = [3, 9, ½, 17, ⅓, 5]
max_result = reduce(lambda x, y: x if x > y else y, numbers)
print(max_result) # 输出:17
这个例子中,累加器函数比较两个数的大小,返回较大的那个。reduce()
通过逐对比较列表中的数值来找出最大值:
3 与 9 比较,返回 9
9 与 ½ 比较,返回 9
9 与 17 比较,返回 17
17 与 ⅓ 比较,返回 17
17 与 5 比较,返回 17