Python中的and与or
2017-07-24 15:56:49 +08 字数:1132 标签: Python从C语言家族,进入Python世界的程序员,当心都被Python中的and
与or
骗了!
貌似正常 ¶
如果把Python当Java用,只使用bool类型来做逻辑运算,那么and
和or
的表现都是正常的。
>>> 'yes' if True and False else 'no'
'no'
>>> True and False
False
>>> True or False
True
有些奇怪 ¶
但是,如果像C语言那样,把int也加进来玩,就有些奇怪了。
>>> 'yes' if True and 0 else 'no'
'no'
>>> True and 0
0
>>> True or 0
True
一会儿是0
,一会儿是True
。
Python不是动态强类型吗,怎么做bool运算得到了0
?
到底是怎么回事? ¶
首先,要理解Python中的bool。
Python里没有Java那么严格的Boolean值检查,而是在需要bool类型时,用bool()
去做转换。
C语言里,&&
和||
的运算结果,是1
或0
;
Java里,运算结果是true
或false
。
在Python里,and
和or
的运算结果,却不一定是True
或False
!
以下引自Python官方文档6.11. Boolean operations。
The expression x
and
y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.The expression x
or
y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.
也就是说,x and y
,可以看做y if x else x
;
而x or y
,可以看做x if x else y
。
俺们如果按C语言家族的方式理解,就略有不同。
x and y
,应该相当于bool(x) and bool(y)
;
x or y
,应该相当于bool(x) and bool(y)
。
这不知道是算Python的设计问题,还是文档问题。
按照它目前的设计,and
和or
就不是什么逻辑运算符,而是值选择符
为什么这样设计 ¶
如果都是用来做逻辑判断,比如if x or y:
,那么它和C语言家族的做法是等价的。
因为,bool(x or y)
,和bool(x) or bool(y)
,是等价的。
区别是,它少做了一次bool转换。
对if x or y:
来说,按照Python目前的做法,
相当于if bool(x if bool(x) else y):
,只有两次bool转换。
而如果按照C语言家族的做法,则是if bool(bool(x) if bool(x) else bool(y))
。
即使两个bool(x)
可以通过编译器优化成一个,也仍然有三次bool转换。
每次基本的and
与or
预算,都少一次bool转换,这优化着实不小。
也许,这就是为什么这么设计。
值选择符 ¶
既然如此,那么and
和or
其实并非在做逻辑运算,而是在选择表达式的值。
一般or
会用得多一些。
a = x or y or z
这一句表示,如果x
非空非None
,则给a
赋值为x
;
否则判断y
,为空则赋值z
。
从更抽象的角度来说,a
从x
、y
、z
三者中选取一个非空非None
的值,优先级为x > y > z
。
它相当于:
a = x if x else y if y else z
用or
来表达,不仅更简洁,还更容易继续增长。
相对来说,and
就不那么常用了。
毕竟,很少会优先挑选空值。
参考 ¶
- 官方文档:6.11. Boolean operations
- 此前的一篇笔记:Python中的bool