divmod(a, b)
divmod(a,b)是Python内置函数,用于返回两个数相除的商和余数,返回值是一个元组(tuple)。
divmod(a, b)
是 Python 的内置函数,用于同时计算两个数值的商和余数,返回一个包含这两个结果的元组 (商, 余数)
。该函数在处理需要同时获取整除结果和余数的场景(如时间单位转换、分页计算)时非常高效。
python
运行
result = divmod(a, b) # 返回 (a // b, a % b)
a
:被除数(数值类型,如整数或浮点数)。b
:除数(数值类型,不可为 0)。(商, 余数)
,其中:
a // b
(整除结果)。a % b
。整数运算:
python
运行
result = divmod(10, 3) # 返回 (3, 1)
# 等价于: (10 // 3, 10 % 3)
浮点数运算:
python
运行
result = divmod(10.5, 3.2) # 返回 (3.0, 0.9)
# 等价于: (10.5 // 3.2, 10.5 % 3.2)
时间单位转换:
python
运行
seconds = 3700
minutes, remainder = divmod(seconds, 60) # 返回 (61, 40)
hours, minutes = divmod(minutes, 60) # 返回 (1, 1)
print(f"{hours}小时{minutes}分钟{remainder}秒") # 输出: 1小时1分钟40秒
ZeroDivisionError
。python
运行
divmod(10, -3) # 返回 (-4, 2),因为 10 = (-4)×(-3) + 2
divmod(-10, 3) # 返回 (-4, 2),因为 -10 = (-4)×3 + 2
divmod(0.1, 0.2)
返回 (0.0, 0.1)
)。通过 divmod
,可以避免多次计算商和余数,提高代码效率。
在Python3中,下列说法正确的是:
sets = {1, 2, 3, 4, 5}
print(sets[2])
程序运行结果为:
A 2
B 3
C 报错
D {3}
正确答案是 C. 报错。
集合(set)的特性:
sets[2]
)访问元素。代码错误:
python
sets = {1, 2, 3, 4, 5} # 创建一个集合
print(sets[2]) # 尝试通过索引访问,报错!
sets[2]
时,Python 会抛出 TypeError: 'set' object is not subscriptable
,提示集合不支持下标操作。python
运行
print(3 in sets) # 输出: True
python
运行
for element in sets:
print(element) # 输出顺序不确定(如 1, 2, 3, 4, 5 或其他顺序)
python
运行
sets.add(6) # 添加元素
sets.remove(4) # 删除元素
union_set = sets | {4, 5, 6} # 并集
python
运行
my_list = [1, 2, 3, 4, 5]
print(my_list[2]) # 输出: 3(列表有序,支持索引)
python
运行
from collections import OrderedDict
ordered_set = OrderedDict.fromkeys([1, 2, 3, 4, 5])
print(list(ordered_set.keys())[2]) # 输出: 3
操作 | 集合(set) | 列表(list) |
---|---|---|
元素唯一性 | 自动去重 | 允许重复 |
顺序性 | 无序 | 有序 |
索引访问 | ❌ 不支持 | ✅ 支持(如 [2] ) |
成员检测效率 | O (1)(哈希表) | O (n)(遍历) |
添加元素 | add() |
append() , insert() |
集合(set)适用于去重和快速成员检测,但不支持索引访问。
若需要有序且可索引的数据结构,应使用列表(list)或有序字典(OrderedDict)。
Python 中字符串的前导 r
代表原始字符串标识符,该字符串中的特殊符号不会被转义,适用于正则表达式中繁杂的特殊符号表示。
在 Python 中,字符串前的 r
表示原始字符串(raw string)
其中的特殊转义字符(如 \n
、\t
等)会被直接视为普通字符,而不会被解释为特殊含义。
python
运行
print(r"\nwoow")
r
前缀使字符串保持原始形式。plaintext
\nwoow
\n
不会被解释为换行符,而是作为两个普通字符 \
和 n
输出。字符串类型 | 表示方式 | 解释结果 |
---|---|---|
普通字符串 | "hello\nworld" |
换行符分隔两行:hello world |
原始字符串 | r"hello\nworld" |
包含 \n 的单行:hello\nworld |
正则表达式:
\
(如 \d
、\s
),使用原始字符串可避免额外转义。python
运行
import re
pattern = r'\d+' # 等价于普通字符串 '\\d+'
文件路径:
python
运行
path = r'C:\Users\Documents' # 无需写成 'C:\\Users\\Documents'
特殊符号:
\1
、Unicode 转义 \uXXXX
等。python
运行
regex = r'(\w+)\1' # 匹配重复单词(如 "hellohello")
原始字符串不能以单个反斜杠结尾:
python
运行
r'C:\temp\' # 语法错误!
r'C:\temp\\' # 正确:双反斜杠表示一个反斜杠
r'C:\temp' # 正确:不以反斜杠结尾
引号仍需转义:
python
运行
r'"hello"' # 正确:双引号在单引号字符串中无需转义
r'\"hello\"' # 错误:原始字符串中的 \ 不会转义 "
r
前缀的作用:禁用字符串中的转义字符,使 \
成为普通字符。\
的字符串。\
结尾。在python3中,对于列表lists=[20, 28, 15, 19, 21],下列选项表述正确的是()
A list(map(lambda x: x>20, lists))的结果为[28, 21]
B list(filter(lambda x: x>20, lists))的结果为[28, 21]
C from functools import reduce
reduce(lambda x, y: x+y, lists)的结果为103
D lists.insert(3, 25)返回的值为[20, 28, 25, 15, 19, 21]
正确答案:BC
你的答案:BD
以下是对各选项的详细分析,解释为何正确答案是 B 和 C,而 D 是错误的:
list(map(lambda x: x>20, lists))
的结果为 [28, 21]
错误。
map()
对每个元素应用函数后返回结果列表。lambda x: x>20
返回布尔值(True
或 False
),因此实际结果为: python
运行
[False, True, False, False, True]
filter()
(选项 B)。list(filter(lambda x: x>20, lists))
的结果为 [28, 21]
正确。
filter()
只保留函数返回 True
的元素。lambda x: x>20
筛选出 28
和 21
,结果为: python
运行
[28, 21]
reduce(lambda x, y: x+y, lists)
的结果为 103
正确。
reduce()
从左到右累积计算。对于 lists = [20, 28, 15, 19, 21]
:
20 + 28 = 48
48 + 15 = 63
63 + 19 = 82
82 + 21 = 103
lists.insert(3, 25)
返回的值为 [20, 28, 25, 15, 19, 21]
错误。
insert()
原地修改列表,但不返回修改后的列表,而是返回 None
。正确的操作应为: python
运行
lists.insert(3, 25) # 插入元素 25 到索引 3 处
print(lists) # 输出: [20, 28, 15, 25, 19, 21]
filter()
筛选元素,reduce()
累加元素。insert()
不返回列表,而是直接修改原列表。map()
返回布尔值列表,而非筛选结果。在 Python 中,映射类型(Mapping Type) 是一种存储键值对(key-value pairs)的数据结构,允许通过键(key)快速查找对应的值(value)。映射类型的核心特点是 键的唯一性 和 高效的查找效率(基于哈希表实现)。
Python 中最常用的映射类型是 字典(dict
),它是 可变的、无序的(Python 3.7+ 后保持插入顺序)。
python
运行
# 创建字典
person = {
"name": "Alice",
"age": 30,
"city": "New York"
}
# 访问值
print(person["name"]) # 输出: Alice
# 修改值
person["age"] = 31
# 添加新键值对
person["job"] = "Engineer"
# 删除键值对
del person["city"]
键必须是可哈希的(hashable):
int
, float
, str
, tuple
, frozenset
。list
, dict
)不能作为键,因为它们是可变的。值可以是任意类型:
python
运行
complex_dict = {
"numbers": [1, 2, 3],
"nested": {"a": 1, "b": 2},
"function": lambda x: x**2
}
键的唯一性:
重复的键会覆盖原有值:
python
运行
d = {"x": 1, "x": 2}
print(d) # 输出: {'x': 2}
内置方法:
python
运行
person.keys() # 返回所有键的视图
person.values() # 返回所有值的视图
person.items() # 返回所有键值对的视图
person.get("age") # 获取值,不存在时返回默认值(None)
person.pop("age") # 删除并返回指定键的值
python
运行
from collections import defaultdict
# 默认值为 0 的字典
counter = defaultdict(int)
counter["apple"] += 1 # 无需先初始化键
print(counter["apple"]) # 输出: 1
dict
已默认支持):python
运行
from collections import OrderedDict
od = OrderedDict()
od["a"] = 1
od["b"] = 2
print(list(od.keys())) # 输出: ['a', 'b']
python
运行
from collections import ChainMap
d1 = {"x": 1}
d2 = {"y": 2}
chain = ChainMap(d1, d2)
print(chain["x"]) # 输出: 1
python
运行
from collections import Counter
words = ["apple", "banana", "apple"]
count = Counter(words)
print(count["apple"]) # 输出: 2
python
运行
from collections import UserDict
class MyDict(UserDict):
def __missing__(self, key):
return f"Key '{key}' not found"
Python 通过 collections.abc
模块提供映射类型的抽象基类,用于类型检查或自定义实现:
python
运行
from collections.abc import Mapping, MutableMapping
# 检查对象是否为映射类型
isinstance({}, Mapping) # 返回: True
isinstance([], Mapping) # 返回: False
类型 | 特点 | 适用场景 |
---|---|---|
dict |
内置、可变、无序(3.7+ 有序) | 通用键值存储 |
defaultdict |
自动初始化不存在的键 | 简化计数或分组操作 |
OrderedDict |
保持插入顺序 | 需要顺序敏感的场景 |
Counter |
高效计数 | 统计元素频率 |
ChainMap |
合并多个映射 | 配置管理、局部 / 全局变量 |
映射类型是 Python 中最强大的数据结构之一,广泛用于数据存储、缓存、配置管理等场景。
装饰器(Decorator) 是 Python 中一种特殊的函数或类,用于在不修改原函数代码的前提下,动态扩展其功能。它通过将原函数包装在另一个函数中,实现功能的增强,体现了面向切面编程(AOP) 的思想。
核心作用:
装饰器的本质是一个高阶函数,它接收一个函数作为参数,并返回一个新的函数。其执行流程如下:
定义装饰器函数:
python
运行
def decorator(func):
def wrapper(*args, **kwargs):
# 前置操作(如计时开始)
result = func(*args, **kwargs) # 调用原函数
# 后置操作(如计时结束)
return result
return wrapper # 返回包装后的函数
应用装饰器:
python
运行
@decorator
def original_function():
pass
等价转换:
上述代码等价于:
python
运行
original_function = decorator(original_function)
python
运行
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs) # 执行原函数
end_time = time.time()
print(f"{func.__name__} 运行时间: {end_time - start_time:.2f}秒")
return result
return wrapper
@timer
def calculate_sum(n):
return sum(range(n + 1))
# 调用被装饰的函数
calculate_sum(1000000) # 输出: calculate_sum 运行时间: 0.05秒
若装饰器需要接受额外参数(如配置项),需使用三层嵌套函数:
python
运行
def repeat(n): # 装饰器工厂函数,接收装饰器参数
def decorator(func):
def wrapper(*args, **kwargs):
result = None
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3) # 传入装饰器参数
def greet():
print("Hello!")
greet() # 输出三次 "Hello!"
直接使用装饰器会导致原函数的元信息(如 __name__
、__doc__
)丢失。可使用 functools.wraps
解决:
python
运行
from functools import wraps
def my_decorator(func):
@wraps(func) # 保留原函数元信息
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@my_decorator
def example():
"""这是示例函数"""
pass
print(example.__name__) # 输出: example(而非 wrapper)
print(example.__doc__) # 输出: 这是示例函数
除了函数装饰器,还可以用类实现装饰器,通过 __call__
方法:
python
运行
class CountCalls:
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"第 {self.count} 次调用 {self.func.__name__}")
return self.func(*args, **kwargs)
@CountCalls
def say_hello():
print("Hello!")
say_hello() # 输出: 第 1 次调用 say_hello
say_hello() # 输出: 第 2 次调用 say_hello
多个装饰器可叠加使用,执行顺序从上到下:
python
运行
@decorator1
@decorator2
def func():
pass
# 等价于:
func = decorator1(decorator2(func))
functools.lru_cache
)。装饰器通过高阶函数或类,在不修改原代码的情况下扩展功能,遵循开放封闭原则(对扩展开放,对修改封闭)。其核心是函数嵌套和闭包,掌握 functools.wraps
和参数传递是进阶关键。
有如下函数定义,执行结果为True的是:
def dec(f):
n= 3
def wrapper(*args,**kw):
return f(*args,**kw) * n
return wrapper
@dec
def foo(n):
return n * 2
A foo(2) == 12
B foo(3) == 12
C foo(2) == 6
D foo(3) == 6
正确答案:A
这道题考察了Python装饰器的基本概念和运行机制。当使用@dec装饰器修饰foo函数时,实际上进行了如下转换:foo = dec(foo)。
让我们分析执行过程:
1. 原始的foo(n)函数会返回n * 2
2. 装饰器dec中定义了n=3,并通过wrapper函数将原始函数的返回值乘以3
3. 所以当调用foo(2)时:
- 首先计算原始函数结果: 2 * 2 = 4
- 然后装饰器将结果乘以3: 4 * 3 = 12
因此foo(2) == 12这个表达式结果为True,A选项正确。
在 Python 中,列表(list)的删除操作主要通过以下方法实现。根据删除需求(按索引、按值、清空或删除切片),可选择不同的方法:
del
语句:按索引或切片删除语法:
python
运行
del list_name[index] # 删除单个元素
del list_name[start:end] # 删除切片(连续范围)
del list_name[::step] # 删除间隔元素
特点:
IndexError
)。示例:
python
运行
nums = [10, 20, 30, 40, 50]
del nums[2] # 删除索引 2 的元素:[10, 20, 40, 50]
del nums[1:3] # 删除索引 1 到 2 的元素:[10, 50]
del nums[::2] # 删除偶数索引元素:[20, 40]
list.pop(index)
:按索引删除并返回值语法:
python
运行
value = list_name.pop(index) # 默认删除最后一个元素(index=-1)
特点:
IndexError
)。示例:
python
运行
fruits = ["apple", "banana", "cherry"]
popped = fruits.pop(1) # 删除索引 1 的元素,popped="banana"
print(fruits) # 输出: ['apple', 'cherry']
list.remove(value)
:按值删除第一个匹配项语法:
python
运行
list_name.remove(value)
特点:
ValueError
)。示例:
python
运行
nums = [1, 2, 3, 2]
nums.remove(2) # 删除第一个 2
print(nums) # 输出: [1, 3, 2]
list.clear()
:清空列表所有元素语法:
python
运行
list_name.clear()
特点:
del list_name[:]
。[]
,但对象仍存在。示例:
python
运行
data = [1, 2, 3]
data.clear() # data 变为 []
语法:
python
运行
new_list = [x for x in old_list if condition]
特点:
示例:
python
运行
nums = [1, 2, 3, 4, 5]
even_nums = [x for x in nums if x % 2 == 0] # 新列表: [2, 4]
filter()
函数:按条件过滤元素语法:
python
运行
new_list = list(filter(lambda x: condition, old_list))
特点:
list()
转换为列表。示例:
python
运行
nums = [1, 2, 3, 4, 5]
even_nums = list(filter(lambda x: x % 2 == 0, nums)) # 新列表: [2, 4]
方法 | 删除方式 | 修改原列表 | 返回值 | 不存在时的错误 |
---|---|---|---|---|
del list[index] |
按索引或切片 | ✅ | 无 | IndexError |
list.pop(index) |
按索引 | ✅ | 被删除的值 | IndexError |
list.remove(value) |
按值(第一个) | ✅ | 无 | ValueError |
list.clear() |
全部元素 | ✅ | 无 | 无 |
列表推导式 | 按条件过滤 | ❌ | 新列表 | 无 |
filter() |
按条件过滤 | ❌ | 迭代器(需转为列表) | 无 |
循环中删除元素:
remove()
或 pop()
可能导致索引错位(如跳过元素)。python
运行
# 错误示例:
nums = [1, 2, 3, 4]
for num in nums:
if num % 2 == 0:
nums.remove(num) # 结果: [1, 3](跳过 4)
# 正确示例:
nums = [1, 2, 3, 4]
nums = [x for x in nums if x % 2 != 0] # 结果: [1, 3]
多维列表:
python
运行
matrix = [[1, 2], [3, 4]]
del matrix[0][1] # 删除第一个子列表的第二个元素
print(matrix) # 输出: [[1], [3, 4]]
性能考虑:
pop(0)
)的时间复杂度为 O (n),性能较差。collections.deque
。在 Python 中,字符串的查找方法在处理不存在的目标时,采用了不同的异常处理机制。以下是对 index()
、count()
、in
和 find()
的详细介绍及异常处理说明:
str.index(sub[, start[, end]])
sub
在原字符串中第一次出现的索引,若未找到则抛出异常。sub
不存在,抛出 ValueError: substring not found
。python
运行
s = "hello"
print(s.index("l")) # 输出: 2
print(s.index("world")) # 报错: ValueError
str.count(sub[, start[, end]])
sub
在原字符串中出现的次数,若未找到则返回 0(不抛异常)。0
。python
运行
s = "hello"
print(s.count("l")) # 输出: 2
print(s.count("world")) # 输出: 0
in
sub
是否存在于原字符串中,返回 True
或 False
(不抛异常)。python
运行
s = "hello"
print("l" in s) # 输出: True
print("world" in s) # 输出: False
str.find(sub[, start[, end]])
sub
在原字符串中第一次出现的索引,若未找到则返回 -1
(不抛异常)。-1
。python
运行
s = "hello"
print(s.find("l")) # 输出: 2
print(s.find("world")) # 输出: -1
方法 | 未找到时的行为 | 适用场景 |
---|---|---|
index() |
抛出 ValueError |
需要明确处理不存在情况的逻辑 |
count() |
返回 0 |
统计出现次数,无需关心是否存在 |
in |
返回 False |
简单的存在性判断 |
find() |
返回 -1 |
需要索引位置,且希望避免异常处理 |
使用 try-except
处理 index()
:
python
运行
s = "hello"
try:
idx = s.index("world")
except ValueError:
print("子字符串不存在")
优先使用 find()
替代 index()
避免异常:
python
运行
s = "hello"
idx = s.find("world")
if idx != -1:
print(f"位置: {idx}")
else:
print("子字符串不存在")
结合 in
和 index()
提高健壮性:
python
运行
s = "hello"
if "world" in s:
idx = s.index("world")
else:
print("子字符串不存在")
in
和 find()
的性能通常优于 index()
,因为它们在找到目标后立即返回,而 index()
需要进行额外的异常检查。in
或 find()
。