【小白笔记】Python 中 `*` 运算符在不同数据类型上的用法
Python 中 * 运算符在不同数据类型上的用法。
这个符号在 Python 中是多态的(Polymorphic),即它根据操作数的类型 扮演着不同的角色。
1. 字符串 (str) 和 * (重复操作)
这是您例子中展示的用法。当 * 的一个操作数是字符串,另一个操作数是整数时,它执行的是重复操作。
| 运算符 | 类型 | 示例 | 结果 | 解释 |
|---|---|---|---|---|
str * int |
重复 | "你好!" * 3 |
"你好!你好!你好!" |
将字符串内容重复 nnn 次并连接起来。 |
int * str |
重复 | 3 * "你好!" |
"你好!你好!你好!" |
顺序不影响结果。 |
2. 列表 (list) 和元组 (tuple) 的 * (重复操作)
与字符串类似,* 也可以用于列表和元组的重复。
| 运算符 | 类型 | 示例 | 结果 | 解释 |
|---|---|---|---|---|
list * int |
重复 | [1, 2] * 3 |
[1, 2, 1, 2, 1, 2] |
将列表中的元素序列重复 nnn 次。 |
tuple * int |
重复 | (1, 2) * 3 |
(1, 2, 1, 2, 1, 2) |
将元组中的元素序列重复 nnn 次。 |
⚠️ 注意深浅拷贝问题:
对于包含可变对象(如另一个列表)的列表重复时,它只是复制了引用。例如:a = [[0]] * 3 # a 的结果是 [[0], [0], [0]] a[0][0] = 99 # 此时 a 的结果是 [[99], [99], [99]],因为它们都指向同一个内部列表。
3. 数字 (int, float) 的 * (乘法操作)
当 * 的两个操作数都是数字类型时,它执行的是基本的数学乘法。
| 运算符 | 类型 | 示例 | 结果 | 解释 | |
| :—: | :—: | :—: | :—: | :— |
| int * int | 乘法 | 5 * 4 | 20 | 标准整数乘法。 |
| float * int | 乘法 | 3.5 * 2 | 7.0 | 浮点数乘法。 |
4. 函数定义/调用中的 * 和 ** (解包和可变参数)
这是 * 在 Python 中最复杂、但也最强大的用法之一,它用于处理可变数量的参数或解包容器。
A. 可变位置参数 (*args)
在函数定义中,* 放在参数前表示该参数将收集所有额外的、未命名的位置参数,并将它们打包成一个元组。
def my_sum(*numbers):
# numbers 是一个元组,例如 (1, 2, 3)
return sum(numbers)
result = my_sum(1, 2, 3, 4)
# result 是 10
B. 解包可迭代对象 (Unpacking)
在函数调用或列表/元组定义中,* 放在可迭代对象前,表示将其解包(展开)成单独的位置参数或元素。
data = [10, 20, 30]
# 1. 函数调用:将列表元素作为独立的参数传入
print(*data) # 等同于 print(10, 20, 30)
# 2. 列表/元组合并:
combined = [5, *data, 40]
# combined 是 [5, 10, 20, 30, 40]
C. 可变关键字参数 (**kwargs)
在函数定义中,** 放在参数前表示该参数将收集所有额外的、未匹配的关键字参数,并将它们打包成一个字典。
def display_info(name, **details):
# details 是一个字典,例如 {'age': 30, 'city': 'New York'}
print(f"Name: {name}, Details: {details}")
display_info("Alice", age=30, city="New York")
D. 解包字典 (Dictionary Unpacking)
在函数调用或字典定义中,** 放在字典前,表示将其解包成独立的键值对作为关键字参数。
config = {'host': '127.0.0.1', 'port': 8080}
default_config = {'timeout': 60, **config}
# default_config 是 {'timeout': 60, 'host': '127.0.0.1', 'port': 8080}
总结表格
| 场景 | 符号 | 操作数类型 | 作用 | 示例 |
|---|---|---|---|---|
| 基础数学 | * |
数字 ×\times× 数字 | 乘法 | 5 * 4 |
| 序列操作 | * |
序列 ×\times× 整数 | 重复(Repeat) | "a" * 3 或 [1] * 3 |
| 函数定义 | * |
参数名 | 收集可变位置参数(*args) |
def func(*a): ... |
| 函数定义 | ** |
参数名 | 收集可变关键字参数(**kwargs) |
def func(**k): ... |
| 解包/合并 | * |
可迭代对象 | 解包元素作为参数或合并序列 | print(*[1, 2]) |
| 解包/合并 | ** |
字典 | 解包键值对作为关键字参数或合并字典 | {'a': 1, **d} |
这个 used=[False]*len(nums) 是 Python 编程中一种非常常见的用法,尤其是在处理回溯法(Backtracking)或者需要跟踪元素使用状态的算法问题中。
它的作用是创建一个布尔值列表(或称为布尔数组),用来标记与另一个列表 nums 中元素对应的位置是否已经被使用或访问过。
🔍 详细解释
1. 语法拆解
len(nums): 首先计算列表nums中元素的个数(长度)。[False]: 这是一个包含单个布尔值False的列表。* len(nums): 这是 Python 中列表的乘法操作。它将左边的列表重复右边指定的次数。used = ...: 将重复操作的结果赋值给变量used。
2. 结果和含义
如果 nums = [1, 2, 3],那么 len(nums) 就是 333。
执行 used = [False] * 3 的结果就是:
used=[False,False,False] used = [False, False, False] used=[False,False,False]
- 长度一致性:
used列表的长度将始终与nums列表的长度相同。 - 初始状态: 列表中的所有元素初始都被设置为
False,表示nums中的所有元素在程序开始时都尚未被使用。
3. 典型应用场景
这个 used 列表最常用于全排列(Permutations)、组合(Combinations)或子集(Subsets)等涉及到选择和去重的回溯算法中。
举例说明(全排列问题):
假设我们要找出列表 nums = [1, 2, 3] 的所有排列。
- 开始时:
used = [False, False, False]。 - 第一层选择:
- 如果选择
nums[0](即 111),则将used[0]设置为True。 - 状态更新:
used = [True, False, False]。
- 如果选择
- 第二层选择:
- 此时,我们只能在
used为False的位置中选择,即nums[1](222)或nums[2](333)。 - 如果选择
nums[1](222),则将used[1]设置为True。 - 状态更新:
used = [True, True, False]。
- 此时,我们只能在
- 回溯时: 当一个排列(例如
[1, 2, 3])生成完毕后,程序会回退到上一步,并将对应的used标记重置为False,以便在下一条路径中重复使用该元素。
💡 总结
| 部分 | 描述 |
|---|---|
| 用途 | 创建一个布尔标志数组,用于跟踪 nums 中元素是否已被选中、访问或使用。 |
| 长度 | 与 nums 列表的长度相同。 |
| 初始值 | 全部为 False。 |
| 场景 | 回溯法、深度优先搜索(DFS)、全排列、组合等算法。 |
更多推荐
所有评论(0)