0

我正在学习 python 列表理解并看到一个用法,但在官方文档中找不到解释。

>>>[(not i%2)*'a' or str(i) for i in range(10)]
>>>['a', '1', 'a', '3', 'a', '5', 'a', '7', 'a', '9']

我试图以这种方式抽象这种用法:

[statement1 or statement2 for i in range(10)]

如果statement1被评估为false,那么使用statement 2,对吗?

我还发现,如果我运行以下命令:

>>> [(not i%2)*'a' and str(i) for i in range(10)]

输出将是:

>>> ['0', '', '2', '', '4', '', '6', '', '8', '']

我该如何理解这些?

4

4 回答 4

2

这是正确的。奇怪的部分是第一个表达式:

(不是 i%2)*'a'

如果 i 是奇数,则计算结果为 'a';如果偶数,它是假的。这是对 Python 中布尔定义的公然滥用(又名专家把戏)。

如果您将True想象为 1,将False想象为 0,那是有道理的。如果乘积为 0,则or运算符将其视为False

这也利用了表达式短路:如果or的左元素是True,则根本不计算右元素,并且该左元素成为表达式的值。

同样,在您后面的示例中,and短路以另一种方式工作:如果左元素为False,则它成为结果;否则,正确的元素成为结果。

于 2016-10-27T23:15:57.033 回答
0

如果将其转换为元组列表(包括两个条件),则更容易看到发生了什么:

>>> [((not i%2)*'a', str(i)) for i in range(10)]
[('a', '0'), ('', '1'), ('a', '2'), ('', '3'), ('a', '4'), ('', '5'), ('a', '6'), ('', '7'), ('a', '8'), ('', '9')]

i 产生的任何奇数值''都是FalsePython 意义上的。然后or计算右侧并返回而不是左侧:

>>> 'LH' or 'RH'
'LH'
>>> '' or 'RH'
'RH'

最好将其表述为条件表达式,因为它易于阅读:

>>> ['a' if i%2==0 else str(i) for i in range(10)]
['a', '1', 'a', '3', 'a', '5', 'a', '7', 'a', '9']
于 2016-10-28T02:30:01.993 回答
0

此处 或 返回第一个可以评估为 的值True。因此,如果第一个语句返回值可以评估为 True,则只需使用它或搜索下一个值。尝试添加更多“或”

 [(not i%3)*'a' or (not i%5)*'b'  or 'c' for i in range(10)]
 => ['a', 'c', 'c', 'a', 'c', 'b', 'a', 'c', 'c', 'a']

并且仅当所有值都可以评估为时才返回最后一个值True

于 2016-10-27T23:18:27.937 回答
0

声明解释说:

not i%2:对偶数i % 2求值,对奇数求值。将产生一个否定以下表达式的布尔值。=>和=> 。01notnot 1Falsenot 0True

(True)*'a'=> 1 * 'a'=>'a'

(False)*'a'=> 0 * 'a'=>''

'',当转换为布尔值时,被评估为False

False or str(i)=>str(i)

于 2016-10-27T23:20:34.683 回答