Python 'and/or' 在表达式中是什么意思,`(not i%2)` 测试什么?
Python what do 'and/or' mean in expression, and what does `(not i%2)` test?
我正在学习python list comprehension 并看到一个用法,但我在官方文档中找不到解释。
>>>[(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', '']
这些应该怎么理解?
没错。奇怪的部分是第一个表达式:
(not i%2)*'a'
如果 i 是奇数,则计算结果为 'a';如果偶数,则为 False。这是对 Python.
中布尔定义的公然滥用(a.k.a。专家技巧)
如果您将 True 想象为 1,将 False 想象为 0,这是有道理的。如果乘积为 0,则 or 运算符将其视为 False。
这也利用了表达式短路:如果 or 的左边元素是 True,那么右边的元素就是' 完全计算,左边的元素成为表达式的值。
同样,在您后面的示例中,and 短路以另一种方式工作:如果左侧元素为 False,则它成为结果;否则,正确的元素成为结果。
此处或 return 第一个可以计算为 True
的值。
所以如果第一个语句 return 值可以被评估为 True,就使用它或搜索下一个值。
尝试添加更多 'or'
[(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']
和return仅当所有值都可以计算为True
时才是最后一个值
声明解释:
not i%2
:对于偶数,i % 2
的计算结果为 0
,对于奇数的计算结果为 1
。 not
将产生一个否定以下表达式的布尔值。 not 1
=> False
, not 0
=> True
.
(True)*'a'
=> 1 * 'a'
=> 'a'
(False)*'a'
=> 0 * 'a'
=> ''
''
,当转换为布尔值时,计算为 False
False or str(i)
=> str(i)
如果将其转换为元组列表(包括两个条件),则更容易看出发生了什么:
>>> [((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 的任何奇数值都会产生 ''
,即 Python 意义上的 False
。然后 or
计算右侧,returns 而不是左侧:
>>> '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']
我正在学习python list comprehension 并看到一个用法,但我在官方文档中找不到解释。
>>>[(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', '']
这些应该怎么理解?
没错。奇怪的部分是第一个表达式:
(not i%2)*'a'
如果 i 是奇数,则计算结果为 'a';如果偶数,则为 False。这是对 Python.
中布尔定义的公然滥用(a.k.a。专家技巧)如果您将 True 想象为 1,将 False 想象为 0,这是有道理的。如果乘积为 0,则 or 运算符将其视为 False。
这也利用了表达式短路:如果 or 的左边元素是 True,那么右边的元素就是' 完全计算,左边的元素成为表达式的值。
同样,在您后面的示例中,and 短路以另一种方式工作:如果左侧元素为 False,则它成为结果;否则,正确的元素成为结果。
此处或 return 第一个可以计算为 True
的值。
所以如果第一个语句 return 值可以被评估为 True,就使用它或搜索下一个值。
尝试添加更多 'or'
[(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']
和return仅当所有值都可以计算为True
声明解释:
not i%2
:对于偶数,i % 2
的计算结果为 0
,对于奇数的计算结果为 1
。 not
将产生一个否定以下表达式的布尔值。 not 1
=> False
, not 0
=> True
.
(True)*'a'
=> 1 * 'a'
=> 'a'
(False)*'a'
=> 0 * 'a'
=> ''
''
,当转换为布尔值时,计算为 False
False or str(i)
=> str(i)
如果将其转换为元组列表(包括两个条件),则更容易看出发生了什么:
>>> [((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 的任何奇数值都会产生 ''
,即 Python 意义上的 False
。然后 or
计算右侧,returns 而不是左侧:
>>> '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']