Python 笔试: reduce · sorted · zip · enumerate · any/all · 推导式 · 生成器
一、zip 专项(第 1~3 题)
第 1 题:zip 配对后取相同值
A = [1, 2, 3, 4]
B = [1, 0, 3, 5]
[a for a, b in zip(A, B) if a == b]
答案:[1, 3]
zip 按位置配对,只保留 a == b 的 a。
第 2 题:zip 长度不一致
list(zip([1, 2, 3], ['a', 'b']))
答案:[(1, 'a'), (2, 'b')]
zip 默认按最短序列截断,多的部分不要。
第 3 题:zip + map + filter 综合
A = ['x', 'y', 'z']
B = [1, 2, 3]
list(map(lambda p: p[0] * p[1], filter(lambda p: p[1] > 1, zip(A, B))))
答案:['yy', 'zzz']
先 zip 得 ('x',1),('y',2),('z',3);filter 保留后两个;map 做字符串重复。
二、enumerate 专项(第 4~5 题)
第 4 题:enumerate 从 0 开始
list(enumerate(['a', 'b', 'c']))
答案:[(0, 'a'), (1, 'b'), (2, 'c')]
enumerate 同时返回索引和值,默认从 0 开始。
第 5 题:enumerate 指定起始索引
[i for i, v in enumerate(['a', 'b', 'c'], start=1) if v != 'b']
答案:[1, 3]
索引从 1 开始,过滤掉值为 'b' 的项。
三、sorted 专项(第 6~8 题)
第 6 题:sorted 不改变原列表
nums = [3, 1, 2]
sorted(nums)
nums
答案:sorted 结果是 [1, 2, 3],但 nums 仍是 [3, 1, 2]。
sorted 返回新列表,不修改原对象。
第 7 题:sorted(key=len)
sorted(['apple', 'pie', 'banana'], key=len)
答案:['pie', 'apple', 'banana']
按字符串长度排序,不是字典序。
第 8 题:sorted + lambda 多级排序
pairs = [(1, 5), (2, 1), (1, 3), (2, 1)]
sorted(pairs, key=lambda x: (x[1], x[0]))
答案:[(2, 1), (2, 1), (1, 3), (1, 5)]
先按第二个元素,再按第一个元素;sorted 稳定,相等时保持原顺序。
四、reduce 专项(第 9~11 题)
第 9 题:reduce 累加
from functools import reduce
reduce(lambda x, y: x + y, [1, 2, 3, 4])
答案:10
过程:1+2=3,3+3=6,6+4=10。x 是累计值,y 是下一个元素。
第 10 题:reduce 带初始值
from functools import reduce
reduce(lambda x, y: x + y, [1, 2, 3, 4, 5], 10)
答案:25
从 10 开始累加:10+1+2+3+4+5=25。
第 11 题:reduce 扁平化列表
from functools import reduce
reduce(lambda x, y: x + y, [[1, 2], [3, 4], [5]], [])
答案:[1, 2, 3, 4, 5]
初始值 [],每次做列表拼接。注意:元素必须是 list,不能是 str。
五、any / all 专项(第 12~14 题)
第 12 题:any 有一个 True 就 True
any([0, '', False, 3])
答案:True
3 是真值,所以 any 返回 True。
第 13 题:all 必须全为真
all([1, 2, 3, 0])
答案:False
0 是假值,只要有一个假值,all 就是 False。
第 14 题:any + 生成器表达式
nums = [-1, -2, 3]
any(x > 0 for x in nums)
答案:True
生成器表达式不会立刻生成列表,但 any 会逐个判断,发现 3>0 就返回 True。
六、列表推导 专项(第 15~17 题)
第 15 题:基础列表推导
[x * 2 for x in range(4) if x % 2 == 0]
答案:[0, 4]
x 取 0,2,分别乘 2。
第 16 题:嵌套推导扁平化
lst = [[1, 2], [3], [4, 5]]
[x for sub in lst for x in sub]
答案:[1, 2, 3, 4, 5]
等价于两层 for:外层遍历子列表,内层遍历元素。
第 17 题:列表推导 vs lambda 陷阱
nums = [1, 2, 3]
[x * 2 for x in nums]
[lambda x: x * 2 for x in nums]
第一行答案:[2, 4, 6]
第二行答案:3 个 lambda 函数的列表,不是 [2,4,6]。
列表推导是“直接算结果”;写 lambda 只是创建函数对象。
七、生成器 专项(第 18~20 题)
第 18 题:生成器表达式 vs 列表推导
g = (x * 2 for x in [1, 2, 3])
type(g)
list(g)
答案:类型是 generator,list(g) 得到 [2, 4, 6]。
圆括号是生成器,方括号是列表;生成器省内存,用时才算。
第 19 题:生成器只能遍历一次
g = (x for x in [1, 2, 3])
list(g)
list(g)
答案:第一次 [1, 2, 3],第二次 []。
生成器耗尽后不会自动重置,这是笔试高频坑。
第 20 题:综合大题
A = [1, 2, 3, 4]
B = [1, 4, 3, 2]
sorted(
[a for a, b in zip(A, B) if a == b],
reverse=True
)
答案:[3, 1]
zip 后相同位置相等的是 1 和 3;sorted reverse 后得 [3, 1]。
这题同时考了 zip、列表推导、sorted。