能否用一行自引用列表推导式生成嵌套列表并省略分支判断?
问题
我需要编写多个生成嵌套列表的列表推导式,简化后的示例代码如下:
foo = [] for i in range(1,3): # 示例用的占位循环 if len(foo) == 0: foo = [[x] for x in (0, 1, -1)] # 能不能省去这一步? else: foo = [f + [x] for f in foo for x in (0, 1, -1)] print(foo)
这段代码的输出是:
[[0, 0], [0, 1], [0, -1], [1, 0], [1, 1], [1, -1], [-1, 0], [-1, 1], [-1, -1]]
我知道可以用itertools实现这个输出,但这里的核心要求是推导式必须基于自身构建(也就是for f in foo)。我想知道能不能省略if, else分支判断,只用一行代码在循环里更新foo?如果直接执行foo = [f + [x] for f in foo for x in (0, 1, -1)],得到的会是空的foo。
解决方案
完全可以,你可以利用Python中or运算符的特性——当foo为空时,foo or 备选值会返回备选值,以此来合并分支:
写法一:直接替换分支逻辑
foo = [] for i in range(1,3): foo = [f + [x] for f in foo or [[x] for x in (0,1,-1)] for x in (0,1,-1)]
更简洁的优化写法
把初始备选值设为[[]]会更简洁,第一次循环时f + [x]就等价于[] + [x],直接生成单元素列表,后续循环再基于已有列表扩展:
foo = [] for i in range(1,3): foo = [f + [x] for f in foo or [[]] for x in (0,1,-1)]
这样就彻底去掉了if-else判断,运行结果和原代码完全一致。原理是:
- 第一次循环时,
foo为空,foo or [[]]返回[[]],推导式生成[[] + [x] for x in (0,1,-1)],也就是[[0], [1], [-1]]; - 第二次循环时,
foo已有值,foo or [[]]返回foo本身,推导式基于已有列表生成更长的嵌套列表。
内容的提问来源于stack exchange,提问作者MikeP
相关产品推荐
相关产品推荐

