使用布尔表达式生成器压平序列

3
我正在寻找一个生成器,它可以根据布尔表达式对元组序列进行平铺。我的数据长这样:

my_data = ((3, 4), (None, 4), (5, 8), (None, 1), (None, 9)...)

我想要做的是将其压缩为一个一维数字生成器,如果元组中的第一项不是None,则取第一项,否则取第二项。我的结果将产生以下序列:
3, 4, 5, 1, 9...

我认为最简单的方法是使用带有短路功能的布尔表达式,但我似乎无法组成一个正确的生成器。我意识到我可以定义一个生成器函数并且这相当直截了当,但我想知道是否可以使用推导式来实现?

我的尝试:

(x or y for subitem in my_data for x, y in subitem)

追踪:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <genexpr>
TypeError: 'int' object is not iterable
2个回答

7
(x[0] or x[1] for x in my_data)

或者,作为替代方案,
(x or y for x,y in my_data)

1
这在 my_data = ((3, 4), (None, 4), (5, 8), (None, 1), (0, None)) 上失败了。 - Tim Pietzcker
Patrick已经澄清,元组的第一个位置永远不会是零,所以我的观点无关紧要。我现在还不能为你的答案投票——我今天已经用完了所有的投票... - Tim Pietzcker

3

我怕你需要明确检查None,否则像(0, None)(0, 1)这样的元组会让你出岔子:

(x if x is not None else y for x,y in my_data)

例子:

>>> my_data = ((3, 4), (None, 4), (5, 8), (None, 1), (0, None), (0, 1))
>>> [x or y for x,y in my_data]
[3, 4, 5, 1, None, 1]
>>> [x if x is not None else y for x,y in my_data]
[3, 4, 5, 1, 0, 0]

对于我的用例,只有在值为非零时才可用,否则为无,但是很好的观点。感谢。 - donopj2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接