使用key参数时max()函数结果异常,如何获取符合长度限制的最长名字?
问题描述
数据文件 names.txt
Ben Lukasz Filippe Sam Artur
现有代码
full_names = (name.strip() for name in open('names.txt')) length = ((name, len(name)) for name in full_names) longest = max(length, key=lambda x: x[1] <= 5) print(longest)
问题
运行结果始终是Ben,但需求是获取长度<=5的最长名字,预期结果为Artur。移除条件将key设为lambda x: x[1]时,max()能正常运行,请问如何修改实现预期输出?
解决方法
方法1:先过滤符合条件的元素,再取最大值
逻辑最直观的方式:先筛选出长度≤5的名字,再在这些结果里找长度最长的:
full_names = (name.strip() for name in open('names.txt')) # 先过滤出符合长度要求的元素,生成(name, 长度)的迭代器 filtered_items = ((name, len(name)) for name in full_names if len(name) <= 5) # 对过滤后的结果取最大值,key为名字长度 longest = max(filtered_items, key=lambda x: x[1]) print(longest) # 输出 ('Artur', 5)
方法2:调整key函数的返回值
如果不想提前过滤,可以修改key函数:对符合条件的名字返回它的长度,不符合的返回一个极小值(比如负无穷),这样max会自动忽略不符合条件的元素,优先选择符合条件里长度最大的:
full_names = (name.strip() for name in open('names.txt')) length = ((name, len(name)) for name in full_names) longest = max(length, key=lambda x: x[1] if x[1] <= 5 else -float('inf')) print(longest) # 输出 ('Artur', 5)
原代码出错原因
原来的key函数lambda x: x[1] <=5返回的是布尔值,Python里True等价于1,False等价于0。所有长度≤5的元素的key都是1,max遇到key相同的元素时,会返回迭代器中第一个出现的元素(也就是Ben),所以得到了错误结果。
内容的提问来源于stack exchange,提问作者dim
相关产品推荐
相关产品推荐

