如何简洁优雅地实现嵌套列表扁平化?已有一行Lambda实现求优化
如何用更简洁优雅的一行代码实现嵌套列表扁平化?
经过大量搜索后我找到如下示例代码:
nested_lists = [[1, 2], [[3, 4], [5, 6], [[7, 8], [9, 10], [[11, [12, 13]]]]]] flattened = lambda *n: (e for a in n for e in (flattened(*a) if isinstance(a, (tuple, list)) else (a,))) print(list(flattened(nested_lists)))该代码可正常运行,输出结果为
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],但代码不够美观且难以理解。我认可其一行代码实现的特性,想知道是否存在更简洁优雅的实现方式?谢谢。
这个问题问得好!你找到的这行代码确实能解决问题,但*n可变参数加上嵌套的生成器表达式,可读性实在拉胯。这里有几个既保持一行特性,又更简洁易懂的方案:
1. 可读性优先的生成器表达式
我们可以把参数改得更明确,调整逻辑顺序,让代码读起来更顺:
flatten = lambda lst: (x for item in lst for x in flatten(item) if isinstance(item, (list, tuple)) else (item,))
这里用了明确的lst参数代替模糊的*n,逻辑也更直观:遍历列表里的每个元素,如果是列表/元组就递归展开,否则直接返回这个元素。生成器的惰性特性也保留了下来。
2. 结合itertools.chain的简洁写法
借助itertools.chain.from_iterable可以自动拼接可迭代对象,省去手动嵌套生成器的麻烦:
from itertools import chain flatten = lambda lst: chain.from_iterable(flatten(item) if isinstance(item, (list, tuple)) else [item] for item in lst)
调用时同样用list(flatten(nested_lists))就能得到目标结果。对于非列表/元组的元素,我们把它包装成单元素列表,让chain能统一处理所有情况,代码整体更紧凑。
3. Python 3.10+ 模式匹配的现代写法
如果你用的是Python 3.10及以上版本,模式匹配能让递归判断更清晰,几乎像自然语言一样:
flatten = lambda lst: (x for item in lst for x in flatten(item) if match item: case list() | tuple(): ... case _: (item,))
match语句直接明确判断元素类型,不需要isinstance,代码意图一目了然。
这些方案都能得到和你原始代码完全一样的输出,但可读性和优雅度提升了不少。要是你以后不执着于一行代码,写个带注释的普通函数会更易维护,但这些选项完美满足你“一行实现+更优雅”的需求。
内容的提问来源于stack exchange,提问作者hulleyrob
相关产品推荐
相关产品推荐

