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
andy first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.The expression x
ory 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