Python 入门 / Python 基础补充
本文补充 Python 脚本中常见但稍容易混淆的语法。阅读前建议先掌握 Python 入门 / Python 基础。
1. 函数参数
1.1 位置参数和关键字参数
调用函数时,可以按定义顺序传入位置参数,也可以明确写出参数名:
| Python |
|---|
| def connect(host, port, timeout=3):
print(host, port, timeout)
connect('example.com', 443)
connect(host='example.com', port=443, timeout=5)
connect('example.com', timeout=5, port=443)
|
输出:
| Text Output |
|---|
| example.com 443 3
example.com 443 5
example.com 443 5
|
位置参数必须位于关键字参数之前。明确写出含义不直观的参数名,通常更容易阅读。
1.2 解包参数
调用函数时,* 将列表或元组解包为位置参数,** 将字典解包为关键字参数:
| Python |
|---|
| def show_user(name, age, city):
print(name, age, city)
position_args = ['Tom', 25]
keyword_args = {'city': 'Shanghai'}
show_user(*position_args, **keyword_args)
|
输出:
字典中的键必须与函数参数名对应,且同一个参数不能被重复传入。
1.3 接收不定数量的参数
定义函数时,*args 收集多余的位置参数并组成元组,**kwargs 收集多余的关键字参数并组成字典:
| Python |
|---|
| def log_event(event, *tags, **details):
print('event:', event)
print('tags:', tags)
print('details:', details)
log_event('login', 'security', 'user', user_id='u-001', success=True)
|
输出:
| Text Output |
|---|
| event: login
tags: ('security', 'user')
details: {'user_id': 'u-001', 'success': True}
|
只有确实需要接受可变参数时才使用 *args 和 **kwargs。参数含义固定时,明确列出参数名更利于检查和维护。
1.4 仅限关键字的参数
参数列表中单独的 * 表示其后的参数只能按名称传入:
| Python |
|---|
| def request(url, *, timeout=3, use_cache=True):
print(url, timeout, use_cache)
request('https://example.com', timeout=5, use_cache=False)
|
这种写法适合布尔值、超时时间等仅看位置难以理解的参数。
1.5 避免可变默认值
默认参数只在函数定义时创建一次。不要把列表、字典或集合直接作为默认值:
| Python |
|---|
| def append_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(append_item('a'))
print(append_item('b'))
|
输出:
使用 None 并在函数内部创建新容器,可以避免不同调用意外共享同一个对象。
2. Lambda 表达式与推导式
2.1 Lambda 表达式
Lambda 表达式用于创建只包含一个表达式的匿名函数,语法结构如下:

| Python |
|---|
| def add(x, y):
return x + y
lambda_add = lambda x, y: x + y
print(add(1, 2) == lambda_add(1, 2))
|
输出:
Lambda 表达式适合用作排序键等简短参数:
| Python |
|---|
| users = [
{'name': 'Tom', 'age': 25},
{'name': 'Jerry', 'age': 18},
]
result = sorted(users, key=lambda user: user['age'])
print(result)
|
逻辑超过一个简单表达式时,使用具名函数通常更清晰。
2.2 列表推导式
列表推导式可以从一个可迭代对象生成新列表:
| Python |
|---|
| numbers = [1, 2, 3, 4, 5]
squares = [number ** 2 for number in numbers]
even_squares = [number ** 2 for number in numbers if number % 2 == 0]
print(squares)
print(even_squares)
|
输出:
| Text Output |
|---|
| [1, 4, 9, 16, 25]
[4, 16]
|
字典和集合也有类似的推导式:
| Python |
|---|
| names = ['Tom', 'Jerry', 'Tom']
name_lengths = {name: len(name) for name in names}
unique_lengths = {len(name) for name in names}
print(name_lengths)
print(sorted(unique_lengths))
|
输出:
| Text Output |
|---|
| {'Tom': 3, 'Jerry': 5}
[3, 5]
|
推导式包含嵌套循环或复杂条件时,应改用普通 for 循环以保持可读性。
3. 真假值
if、while 和 bool() 会按真假值规则判断对象。以下常见值会被判断为假:
None
- 数字零,例如
0、0.0
- 空字符串
""
- 空容器,例如
[]、()、{}、set()
- 布尔值
False
其他大多数对象会被判断为真:
| Python |
|---|
| values = [0, 1, '', 'False', [], [0], None]
for value in values:
print(f'{value!r}: {bool(value)}')
|
输出:
| Text Output |
|---|
| 0: False
1: True
'': False
'False': True
[]: False
[0]: True
None: False
|
字符串 "False" 不是布尔值 False;它是非空字符串,因此真假值为真。
检查容器是否为空时可以直接使用真假值:
| Python |
|---|
| items = []
if not items:
print('列表为空')
|
4. 常用内置函数
4.1 遍历与配对
| Python |
|---|
| names = ['Tom', 'Jerry', 'Lucy']
scores = [90, 80, 95]
for index, name in enumerate(names, start=1):
print(index, name)
for name, score in zip(names, scores):
print(f'{name}: {score}')
|
输出:
| Text Output |
|---|
| 1 Tom
2 Jerry
3 Lucy
Tom: 90
Jerry: 80
Lucy: 95
|
zip() 以最短的输入为准,较长输入中多余的元素不会出现在结果中。
4.2 聚合与判断
| Python |
|---|
| numbers = [3, 1, 4, 2]
conditions = [True, True, False]
print('元素数量:', len(numbers))
print('最小值:', min(numbers))
print('最大值:', max(numbers))
print('总和:', sum(numbers))
print('全部为真:', all(conditions))
print('至少一个为真:', any(conditions))
|
输出:
| Text Output |
|---|
| 元素数量: 4
最小值: 1
最大值: 4
总和: 10
全部为真: False
至少一个为真: True
|
4.3 排序
sorted() 返回排序后的新列表,可以通过 key 指定排序依据,通过 reverse=True 倒序排列:
| Python |
|---|
| users = [
{'name': 'Tom', 'age': 25},
{'name': 'Jerry', 'age': 18},
{'name': 'Lucy', 'age': 30},
]
result = sorted(users, key=lambda user: user['age'], reverse=True)
print([user['name'] for user in result])
|
输出:
4.4 类型转换
| Python |
|---|
| print(int('5'))
print(float('2.5'))
print(str(100))
print(list((1, 2, 3)))
print(tuple([1, 2, 3]))
print(set([1, 1, 2, 3]))
|
输出集合时顺序不固定;如果需要稳定结果,可以先使用 sorted()。
range() 是惰性可迭代对象,zip()、map() 和 filter() 返回迭代器。它们可以直接用于 for,只有确实需要完整列表时才调用 list()。
5. 字符串格式化
推荐使用 f-string 组合变量和文本:
| Python |
|---|
| name = 'Tom'
age = 25
score = 92.456
print(f'{name} 今年 {age} 岁')
print(f'得分:{score:.2f}')
print(f'完成率:{0.856:.1%}')
print(f'调试表示:{name!r}')
|
输出:
| Text Output |
|---|
| Tom 今年 25 岁
得分:92.46
完成率:85.6%
调试表示:'Tom'
|
常见格式说明如下:
| 写法 |
作用 |
{value:.2f} |
浮点数保留两位小数 |
{value:.1%} |
转换为百分比并保留一位小数 |
{value:>10} |
在宽度为 10 的区域中右对齐 |
{value!r} |
使用 repr() 的表示形式 |
6. 常用字符串方法
6.1 查找和判断
| Python |
|---|
| text = 'Hello, Python!'
print(text.startswith('Hello'))
print(text.endswith('!'))
print('Python' in text)
print(text.find('Python'))
print(text.count('o'))
|
输出:
str.find() 找不到内容时返回 -1;str.index() 找不到内容时抛出 ValueError。只判断是否包含时,优先使用 in。
6.2 分割和合并
| Python |
|---|
| text = 'apple,microsoft,ibm'
items = text.split(',')
print(items)
print(' | '.join(items))
|
输出:
| Text Output |
|---|
| ['apple', 'microsoft', 'ibm']
apple | microsoft | ibm
|
str.join() 只能合并字符串。如果列表中含数字,应先将每个元素转换为字符串。
6.3 清理和替换
| Python |
|---|
| text = ' Hello, World! '
print(repr(text.strip()))
print(repr(text.lstrip()))
print(repr(text.rstrip()))
print(text.strip().replace('World', 'Python'))
|
输出:
| Text Output |
|---|
| 'Hello, World!'
'Hello, World! '
' Hello, World!'
Hello, Python!
|
strip(chars) 中的参数表示需要移除的字符集合,不是完整前缀或后缀。需要移除固定前缀或后缀时,使用 removeprefix() 或 removesuffix():
| Python |
|---|
| print('prefix-value'.removeprefix('prefix-'))
print('report.json'.removesuffix('.json'))
|
7. 可变对象与复制
列表、字典和集合是可变对象。把可变对象赋给另一个变量不会自动复制数据,两个变量仍指向同一个对象:
| Python |
|---|
| original = [1, 2]
alias = original
alias.append(3)
print(original)
|
输出:
需要独立的浅层副本时,可以使用 .copy():
| Python |
|---|
| original = [1, 2]
copied = original.copy()
copied.append(3)
print(original)
print(copied)
|
输出:
浅层复制不会继续复制内部嵌套对象。处理嵌套数据且确实需要完全独立的副本时,可以使用标准库 copy.deepcopy(),但应先确认复制大量数据带来的开销。
8. 下一步
接下来阅读 Python 入门 / Python 内置库,学习如何使用 Python 自带的标准库完成常见任务。