python内置函数
filter方法
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
# 语法:
filter(function, iterable) #function -- 判断函数 iterable -- 可迭代对象。
# 返回值:返回一个迭代器对象
# 案例1:过滤出列表中的所有奇数:
def is_odd(n):
return n % 2 == 1
tmplist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
newlist = list(tmplist)
print(newlist) # [1, 3, 5, 7, 9]
# 案例2:过滤出1~100中平方根是整数的数:
import math
def is_sqr(x):
return math.sqrt(x) % 1 == 0
tmplist = filter(is_sqr, range(1, 101))
newlist = list(tmplist)
print(newlist) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]可以对哪些数据操作
核心:第二个参数必须是可迭代对象 (iterable)
✅ 支持操作的数据类型:
- 列表 list
- 元组 tuple
- 字符串 str(迭代每一个字符)
- 集合 set
- 字典 dict(迭代字典的 key)
- 生成器、迭代器
- range 对象
❌ 不支持:int、float 等普通数字(不是可迭代对象)
代码示例
示例 1:function 为普通函数,过滤列表
def is_even(n):
return n % 2 == 0
nums = [1,2,3,4,5,6]
res = filter(is_even, nums)
print(list(res)) # [2, 4, 6]示例 2:搭配 lambda 匿名函数(最常用)
nums = [1,2,3,4,5,6]
res = filter(lambda x: x>3, nums)
print(list(res)) # [4,5,6]示例 3:function 传 None,过滤掉假值
假值:0, "", [], {}, None, False
data = [0, 1, "", "hello", None, False, 88]
res = filter(None, data)
print(list(res)) # [1, 'hello', 88]示例 4:操作字符串
s = "abc123def456"
# 保留字母
res = filter(lambda c: c.isalpha(), s)
print(list(res)) # ['a','b','c','d','e','f']示例 5:操作元组
t = (-5, 0, 3, -2, 7)
res = filter(lambda x: x>0, t)
print(tuple(res)) # (3,7)示例 6:操作字典,过滤 key
d = {"a":1, "b":2,, "b":2, "c":3}
res = filter(lambda k: k == "a", d)
print(list(res)) # ['a']
"""
【筛选字典数据】
筛选出分数大于85的所有键值对,生成新字典并输出。
测试数据:score_dict = {"语文": 88, "数学": 95, "英语": 90, "物理": 82}
"""
# 方法一:使用字典推导式
score_dict = {"语文": 88, "数学": 95, "英语": 90, "物理": 82}
new_score_dict1 = {k: v for k, v in score_dict.items() if v > 85}
# 方法二:使用filter方法
# 这里 v 实际是(科目,分数)元组,返回的就应该是[(科目,分数)]这样的列表类型的元组,再使用dict强制转换回去即可
# score_dict.items()产出一个个(key,value)的元组:("语文",88)、("数学",95)、("英语",90)、("物理",82)
# filter 做的事:把每一个元组丢给 lambda 判断,把条件为 True 的元组保留下来,做成迭代器。此时迭代器里面存放内容:("语文",88),("数学",95),("英语",90)
# dict()可以接收一种格式:可迭代对象,里面每一项是长度为 2 的元组(k,v)。
new_score_dict2 = dict(filter(lambda v: v[1] > 85, score_dict.items()))
print(new_score_dict1)
print(new_score_dict2)示例 7:操作 range
res = filter(lambda x:x%3==0, range(10))
print(list(res)) # [0,3,6,9]注意要点
- Python3
filter()返回迭代器,只能遍历一次,用完就空;需要多次使用务必转 list/tuple。
r = filter(lambda x:x>1, [1,2,3])
print(list(r)) # [2,3]
print(list(r)) # [] 已经消耗完毕- filter 等价生成器表达式写法(很多场景推荐用生成器可读性更好)
[x for x in nums if x>3]- 第一个函数返回必须是布尔判断;不要做打印、修改元素这类副作用操作,filter 只做筛选。
filter VS 列表推导式对比
表格
| 写法 | 优点 | 缺点 |
|---|---|---|
filter(func, iter) | 函数逻辑可以复用,适合已有判断函数 | py3 返回迭代器,需要转换;lambda 嵌套多可读性下降 |
[x for x in iter if cond] | 直观易懂,代码集中 | 判断逻辑复杂时代码臃肿 |
常见报错
TypeError: 'int' object is not iterable错误原因:第二个参数传了数字,数字不是可迭代对象,filter 不能直接处理数字。
map方法
map(function, *iterables)- function:处理每个元素的函数,可以普通函数、lambda;也可以内置函数
- *iterables:一个或多个可迭代对象
- 返回值:map 迭代器对象,Python3 返回迭代器,需要
list()/tuple()转换查看结果
工作逻辑:把可迭代对象里的每一个元素依次传入函数,将函数返回结果收集起来,不会过滤元素,元素数量和输入一致。
可以对哪些数据操作
参数要求:传入的都必须是可迭代对象 (iterable)
✅ 支持:
- 列表 list
- 元组 tuple
- 字符串 str(迭代单个字符)
- 集合 set
- 字典 dict(只迭代 key)
- range 对象
- 生成器、迭代器
❌ 不支持:int、float 普通数字,直接传数字会报 TypeError: 'int' object is not iterable
map 和 filter 的区别:
filter:筛选,元素个数可能变少,输出原元素map:转换加工,元素个数不变,输出函数处理后的新值
代码示例
示例 1:普通函数,处理列表
def square(x):
return x * x
nums = [1,2,3,4]
res = map(square, nums)
print(list(res)) # [1, 4, 9, 16]示例 2:搭配 lambda 匿名函数(高频)
nums = [1,2,3,4]
res = map(lambda x: x+10, nums)
print(list(res)) # [11, 12, 13, 14]示例 3:传入多个可迭代对象
函数参数数量要和可迭代对象数量匹配;以最短的可迭代对象结束。
a = [1,2,3]
b = [10,20,30]
res = map(lambda x,y: x+y, a, b)
print(list(res)) # [11, 22, 33]示例 4:操作字符串
s = "python"
res = map(lambda c: c.upper(), s)
print(list(res)) # ['P','Y','T','H','O','N']示例 5:操作元组
t = (2,4,6)
res = map(lambda x:x/2, t)
print(tuple(res)) # (1.0, 2.0, 3.0)示例 6:操作 range 对象
res = map(lambda x:x*2, range(5))
print(list(res)) # [0, 2, 4, 6, 8]示例 7:内置函数直接传入 map
str_nums = ["1","2","3"]
res = map(int, str_nums)
print(list(res)) # [1, 2, 3]重要注意点
- map 返回迭代器,只能遍历一次,消耗完毕就为空
r = map(lambda x:x*2, [1,2,3])
print(list(r)) # [2,4,6]
print(list(r)) # []- 多可迭代对象长度不一致时,取最短长度
list1 = [1,2]
list2 = [10,20,30]
res = map(lambda x,y:x+y, list1, list2)
print(list(res)) # [11, 22]- map 的等价列表推导写法
nums = [1,2,3]
# map版本
list(map(lambda x:x**2, nums))
# 列表推导式版本
[x**2 for x in nums]map vs filter 对比表
表格
| 函数 | 作用 | 元素数量变化 | 返回内容 |
|---|---|---|---|
map(func, iter) | 转换 / 加工每一个元素 | 数量不变 | 函数处理后的结果 |
filter(func, iter) | 筛选保留符合条件元素 | 数量可能变少 | 原始元素 |
示例对比:
data = [1,2,3,4]
# map:全部加工
print(list(map(lambda x:x*2, data))) # [2,4,6,8]
# filter:只筛选
print(list(filter(lambda x:x>2, data))) # [3,4]常见报错
TypeError: 'int' object is not iterable
第二个参数传了数字,数字不是可迭代对象。
TypeError: <lambda>() takes 1 positional argument but 2 were given
传入多个可迭代对象,但 lambda 函数参数个数不够。
可以直接复制保存为 python_map.md,和之前 filter 的笔记放一起。
小拓展:
map+filter可以组合使用,先加工再筛选,或者先筛选再加工。
nums = [1,2,3,4,5]
# 先map平方,再filter过滤大于5的
res = filter(lambda x:x>5, map(lambda x:x**2, nums))
print(list(res)) # [9,16,25]map和filter组合使用的案例
"""
将如下列表中能被3 或 5整除的元素提出来,并获取这些数字对应的平方,组成一个新的列表。
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
"""
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
# 需求:将如下列表中能被3 或 5整除的元素提出来,并获取这些数字对应的平方,组成一个新的列表。
# 使用列表推导式
list2 = [num ** 2 for num in list1 if num % 3 == 0 or num % 5 == 0]
print(list2)
# 方法2:使用filter+map组合
# filter(lambda x: x % 3 == 0 or x % 5 == 0, list1),先将符合要求的数据过滤
#再使用map对每一个数据进行操作,但是请注意:map返回的是map 迭代器对象,Python3 返回迭代器,需要list()/tuple() 转换查看结果
list3 = list(map(lambda x: x ** 2, filter(lambda x: x % 3 == 0 or x % 5 == 0, list1)))
print(list3)map和filter的习题练习
Python map / filter 高阶真实场景面试题(8道 进阶难度)
说明:进阶难度、全部为真实业务场景、面试高频考点 | 纯题目无答案 | filter 4题 + map 4题
---
一、Filter 高阶业务场景题(4题)
【场景1:数据清洗——过滤无效用户数据】
# 业务场景:后端用户列表过滤,剔除封号、空昵称、年龄异常的脏数据
# 测试数据:
users = [
{"name": "张三", "age": 20, "status": 1},
{"name": "", "age": 25, "status": 1},
{"name": "李四", "age": 0, "status": 1},
{"name": "王五", "age": 30, "status": 0},
{"name": "赵六", "age": 28, "status": 1}
]
# 需求:使用 filter 保留【昵称非空 + 年龄1-120 + 状态正常(1)】的合法用户
【场景2:日志分析——过滤报错日志】
# 业务场景:运维日志筛选,只保留 ERROR 级别日志,过滤 INFO/WARN
# 测试数据:
logs = [
"INFO: 接口请求成功",
"ERROR: 数据库连接失败",
"WARN: 内存占用过高",
"ERROR: 权限校验异常",
"INFO: 用户登录成功"
]
# 需求:使用 filter 只筛选出包含 ERROR 的错误日志
【场景3:电商业务——过滤可参与活动商品】
# 业务场景:商城活动筛选,价格大于等于100、且库存大于0的上架商品
# 测试数据:
goods = [
{"title": "手机", "price": 1999, "stock": 20},
{"title": "挂件", "price": 29, "stock": 100},
{"title": "耳机", "price": 129, "stock": 0},
{"title": "键盘", "price": 159, "stock": 35}
]
# 需求:使用 filter 筛选出【价格≥100 且 库存>0】的活动商品
【场景4:数据统计——过滤合法邮箱】
# 业务场景:批量过滤用户邮箱,只保留包含 @ 的合法邮箱格式
# 测试数据:
email_list = [
"test@qq.com",
"abc123",
"user@python.org",
"helloworld",
"demo@163.com"
]
# 需求:使用 filter 筛选出所有合法邮箱(包含@符号)
---
二、Map 高阶业务场景题(4题)
【场景5:数据格式化——用户信息字段拼接】
# 业务场景:后端接口返回数据格式化,将用户字典批量拼接为展示文本
# 测试数据:
user_list = [
{"name": "小明", "age": 18},
{"name": "小红", "age": 22},
{"name": "小刚", "age": 20}
]
# 需求:使用 map 批量生成格式:"小明-18岁"、"小红-22岁"
【场景6:价格计算——商品价格批量加价】
# 业务场景:电商调价,所有商品价格上浮 20%,保留2位小数
# 测试数据:
prices = [99.9, 199.5, 299.8, 59.9]
# 需求:使用 map 完成 原价*1.2 并保留两位小数
【场景7:多列表对应合并——批量拼接账号密码】
# 业务场景:自动化测试场景,账号列表、密码列表一一对应拼接
# 测试数据:
usernames = ["user1", "user2", "user3"]
passwords = ["123456", "666666", "888888"]
# 需求:使用 map 一对一拼接成 "user1|123456" 格式字符串列表
【场景8:字段提取——批量提取字典指定字段】
# 业务场景:数据分析,从多条订单数据中批量提取所有订单号
# 测试数据:
order_list = [
{"order_id": "OD2026001", "money": 299},
{"order_id": "OD2026002", "money": 599},
{"order_id": "OD2026003", "money": 199}
]
# 需求:使用 map 批量提取所有 order_id 生成纯订单号列表
---
刷题要求(面试标准)
1. 全部只能使用 map / filter 完成,禁止 for 循环
2. 尽量搭配 lambda 一行代码实现
3. 最终结果必须转为 listsort方法
sort() 是列表 list 的内置方法,只作用于列表;直接修改原列表,返回值为 None。 区分:内置全局函数 sorted(),返回新列表,不改动原数据。
# sort方法的语法如下:
list.sort(数据源, key=None, reverse=False)参数说明
key=None:指定排序规则,接收一个函数对象,以该函数的返回结果作为排序依据,默认直接比较元素本身。reverse=False:布尔值,False升序 (默认),True降序。
⚠️
*分隔符:后面key、reverse只能用关键字传参,不能位置传参。
返回值:
None,原地修改原列表,不要写res = lst.sort(),res 会得到 None。
案例如下:
# 案例 1:普通数字排序
nums = [8, 3, 12, 1, 5]
nums.sort()
print(nums) # [1, 3, 5, 8, 12]
nums.sort(reverse=True)
print(nums) # [12, 8, 5, 3, 1]
# 案例 2:字符串排序(按字符 Unicode 编码)
words = ["banana", "apple", "cat"]
words.sort()
print(words) # ['apple', 'banana', 'cat']
# 案例 3:key 参数,使用普通函数
data = [("张三",22), ("李四",18), ("王五",25)]
def get_age(item):
return item[1] # 返回元组的年龄,按年龄排序
data.sort(key=get_age)
print(data)
# [('李四', 18), ('张三', 22), ('王五', 25)]
案例 4:key 搭配 lambda 匿名函数(最常用)
data = [("张三",22), ("李四",18), ("王五",25)]
# 按年龄升序
data.sort(key=lambda x: x[1])
print(data)
# 按年龄降序
data.sort(key=lambda x:x[1], reverse=True)
print(data)
# 案例 5:按字符串长度排序
lst = ["a", "bc", "defgh", "xyz"]
lst.sort(key=lambda s: len(s))
print(lst) # ['a', 'bc', 'xyz', 'defgh']
# 案例 6:字典列表排序(业务高频)
users = [
{"name":"zhangsan", "age":28},
{"name":"lisi", "age":20},
{"name":"wangwu", "age":33}
]
# 按age升序
users.sort(key=lambda u: u["age"])
print(users)sort () 和 sorted () 核心对比
| 项目 | list.sort() | sorted() |
|---|---|---|
| 归属 | 列表对象方法 | Python 全局内置函数 |
| 原列表 | 原地修改,改变原列表 | 不修改原数据,返回全新列表 |
| 返回值 | None | 返回排序后的新列表 |
| 可处理对象 | 只能 list | 可迭代对象:list、tuple、set、字符串等 |
zip方法
"""
【列表转字典(数据结构化)】
有两个列表 names = ["小明", "小红", "小刚", "小丽"]、ages = [17, 18, 17, 19],将两个列表一一对应,转换为以姓名为键、年龄为值的字典,输出结果。
测试数据:names = ["小明", "小红", "小刚", "小丽"];ages = [17, 18, 17, 19]
"""
names = ["小明", "小红", "小刚", "小丽"]
ages = [17, 18, 17, 19]
user_dict = {v: ages[i] for i, v in enumerate(names)}
print(user_dict)
# 使用zip方法
user_dict1 = dict(zip(names, ages))
print(user_dict1)sorted
这个地方需要补充完整一下。
sorted() 函数对所有可迭代的对象进行排序操作。
sort 与 sorted 区别:
sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。
list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。
语法
sorted 语法:
sorted(可迭代对象, key=None, reverse=False)
"""
【sorted + lambda 对字典的值排序,输出元组列表】
data_dict = {"java":86, "python":95, "go":78, "c++":86}
规则:按分数降序;分数相同按照key(语言名)升序;使用sorted+lambda实现,输出排序后的(key,value)元组列表。
测试数据:data_dict = {"java":86, "python":95, "go":78, "c++":86}
"""
data_dict = {"java":86, "python":95, "go":78, "c++":86}
# 按分数降序;分数相同按照key(语言名)升序
new_data_dict = sorted(data_dict.items(), key=lambda v: (-v[1], v[0]))
print(*new_data_dict)- 第一个参数:可迭代对象 list、tuple、dict、dict.items ()、字符串、集合都可以传给 sorted。
传入字典:默认只对 key 排序
d = {"b":2, "a":1}
print(sorted(d)) # ['a','b'] 只拿字典key- key:排序规则函数 接收一个参数,返回用来比较排序的值;常用
lambda。
key=lambda x: x[0] # 按元组第0项排序
key=lambda x: x[1] # 按元组第1项排序
key=len # 按元素长度排序reverse=False / True
False:升序(默认,从小到大)True:降序(从大到小)
【字典数据排序】
给定成绩字典 rank_dict = {"小明": 76, "小红": 98, "小刚": 89, "小丽": 93},分别实现:1、按分数升序排序;2、按分数降序排序,输出排序后的键值对列表。
测试数据:rank_dict = {"小明": 76, "小红": 98, "小刚": 89, "小丽": 93}
"""
rank_dict = {"小明": 76, "小红": 98, "小刚": 89, "小丽": 93}
# sorted(rank_dict.items(), key=lambda item: item[1])这里返回的是一个长度为2的元组
# key=lambda item: item[1]表示拿第二个数据也就是dict中的value做排序
# 默认升序
rank_dict1 = dict(sorted(rank_dict.items(), key=lambda item: item[1]))
# 降序排列
rank_dict2 = dict(sorted(rank_dict.items(), key=lambda item: item[1], reverse=True))
print(rank_dict1)
print(rank_dict2)案例
场景 1:普通列表排序
nums = [5,2,9,1]
asc = sorted(nums)
desc = sorted(nums, reverse=True)
print(asc) # [1, 2, 5, 9]
print(desc) # [9, 5, 2, 1]场景 2:元组列表,按指定位置元素排序(高频,字典 items 常用)
数据:[("小明",76),("小红",98),("小刚",89)]
x[0]→ 按姓名排序x[1]→ 按分数排序
rank = [("小明",76),("小红",98),("小刚",89)]
res = sorted(rank, key=lambda x:x[1], reverse=True)
print(res)
# [('小红', 98), ('小刚', 89), ('小明', 76)]场景 3:字典按 value 排序(必考)
sorted 不能直接返回字典,返回二元元组列表
rank_dict = {"小明": 76, "小红": 98, "小刚": 89}
# 按分数升序
res = sorted(rank_dict.items(), key=lambda item: item[1])
print(res)
# [('小明', 76), ('小刚', 89), ('小红', 98)]场景 4:按字符串长度排序
words = ["python","go","java","c"]
res = sorted(words, key=len)
print(res) # ['c', 'go', 'java', 'python']场景 5:利用 sorted+dict (),借助后面覆盖前面做去重取最大值(练习题技巧)
data = [("语文", 85), ("数学", 90), ("语文", 90), ("数学", 88), ("英语", 92)]
# 分数升序,高分放后面,dict构造时后面覆盖前面
s_data = sorted(data, key=lambda x:x[1])
d = dict(s_data)
print(d) # {'语文': 90, '数学': 90, '英语': 92}初学者高频坑
- 对字典直接
sorted(dict),只会排序 key,拿不到 value;要排序值务必传.items()
#错误
sorted(rank_dict)
#正确
sorted(rank_dict.items(), key=lambda x:x[1])- sorted 输出永远是列表,不是字典;想要字典需要手动
dict(排序后的列表)。 key只告诉 sorted用什么值比较大小,不会修改原始元素本身。
快速记忆模板
# 按元组第1项升序
sorted(xxx.items(), key=lambda x:x[1])
# 按元组第1项降序
sorted(xxx.items(), key=lambda x:x[1], reverse=True)