如何将实现类似Ansible with_first_found的字典查找循环改为单行代码?
实现类似Ansible
with_first_found 的单行写法 当然可以把这段for/if/break循环改写成更简洁优雅的单行代码!你已经用生成器表达式配合next()摸到了正确方向,我们可以再优化一下可读性和健壮性:
基础单行实现
你写出的这个版本已经能完成核心功能:
first_found = next(configuration[key] for key in lookup if key in configuration)
它会遍历lookup列表,返回第一个存在于configuration字典中的键对应的值,完全替代了原来的循环逻辑。
优化可读性与容错性
不过这个写法有两个可以改进的点:
- 如果
lookup里的所有键都不在configuration中,会抛出StopIteration异常,而原代码有default兜底; - 紧凑的一行可读性稍差,尤其是对不熟悉生成器表达式的人来说。
我们可以给next()加上默认参数,同时拆分换行提升可读性:
first_found = next( (configuration[key] for key in lookup if key in configuration), configuration["default"] )
这样既保留了单行逻辑的简洁,又保证了即使前面的键都没匹配到,也能返回default的值,和原代码的逻辑完全一致。
另外,还有一种更侧重语义直观的写法,用filter()配合next():
first_found = configuration[next(filter(configuration.__contains__, lookup))]
这个写法先通过filter()筛选出lookup中存在于configuration的键,再用next()取第一个匹配的键,最后从字典中取出对应值,逻辑链条非常清晰。
验证效果
当你测试distribution_release = "ubuntu-16.04"时,这几种单行写法都会返回"these options are good for all ubuntu versions",和原代码的输出完全一致。
内容的提问来源于stack exchange,提问作者ebbex
相关产品推荐
相关产品推荐

