在Python 中,and 和 or 执行布尔逻辑演算,如你所期待的一样。但是它们并不返回布尔值,而是返回它们实际进行比较的值之一。

例 4.15. and 介绍

>>> 'a' and 'b'         

'b'
>>> '' and 'b'

''
>>> 'a' and 'b' and 'c'

'c'
使用 and 时,在布尔环境中从左到右演算表达式的值。0''[](){}None 在布尔环境中为假;其它任何东西都为真。还好,几乎是所有东西。默认情况下,布尔环境中的类实例为真,但是你可以在类中定义特定的方法使得类实例的演算值为假。你将会在第 5 章中了解到类和这些特殊方法。如果布尔环境中的所有值都为真,那么 and 返回最后一个值。在这个例子中,and 演算 'a' 的值为真,然后是 'b' 的演算值为真,最终返回 'b'
如果布尔环境中的某个值为假,则 and 返回第一个假值。在这个例子中,'' 是第一个假值。
所有值都为真,所以 and 返回最后一个真值,'c'

例 4.16. or 介绍

>>> 'a' or 'b'          

'a'
>>> '' or 'b'

'b'
>>> '' or [] or {}

{}
>>> def sidefx():
... print "in sidefx()"
... return 1
>>> 'a' or sidefx()

'a'
使用 or 时,在布尔环境中从左到右演算值,就像 and 一样。如果有一个值为真,or 立刻返回该值。本例中,'a' 是第一个真值。
or 演算 '' 的值为假,然后演算 'b' 的值为真,于是返回 'b' 。
如果所有的值都为假,or 返回最后一个假值。or 演算 '' 的值为假,然后演算 [] 的值为假,依次演算 {} 的值为假,最终返回 {} 。
注意 or 在布尔环境中会一直进行表达式演算直到找到第一个真值,然后就会忽略剩余的比较值。如果某些值具有副作用,这种特性就非常重要了。在这里,函数 sidefx 永远都不会被调用,因为 or 演算 'a' 的值为真,所以紧接着就立刻返回 'a' 了。

如果你是一名 C 语言黑客,肯定很熟悉 bool ? a : b 表达式,如果 bool 为真,表达式演算值为 a,否则为 b。基于 Python 中 and 和 or 的工作方式,你可以完成相同的事情。

4.6.1. 使用 and-or 技巧

 

例 4.17. and-or 技巧介绍

>>> a = "first"
>>> b = "second"
>>> 1 and a or b

'first'
>>> 0 and a or b

'second'
这个语法看起来类似于 C 语言中的 bool ? a : b 表达式。整个表达式从左到右进行演算,所以先进行 and 表达式的演算。1 and 'first' 演算值为 'first',然后 'first' or 'second' 的演算值为 'first'
0 and 'first' 演算值为 False,然后 0 or 'second' 演算值为 'second'

然而,由于这种 Python 表达式单单只是进行布尔逻辑运算,并不是语言的特定构成,这是 and-or 技巧和 C 语言中的 bool ? a : b 语法非常重要的不同。如果 a 为假,表达式就不会按你期望的那样工作了。(你能知道我被这个问题折腾过吗?不止一次?)

例 4.18. and-or 技巧无效的场合

>>> a = ""
>>> b = "second"
>>> 1 and a or b

'second'
由于 a 是一个空字符串,在 Python 的布尔环境中空字符串被认为是假的,1 and '' 的演算值为 '',最后 '' or 'second' 的演算值为 'second'。噢!这个值并不是你想要的。

and-or 技巧,也就是 bool and a or b 表达式,当 a 在布尔环境中的值为假时,不会像 C 语言表达式 bool ? a : b 那样工作。

在 and-or 技巧后面真正的技巧是,确保 a 的值决不会为假。最常用的方式是使 a 成为 [a] 、 b 成为 [b],然后使用返回值列表的第一个元素,应该是 a 或 b中的某一个。

例 4.19. 安全使用 and-or 技巧

>>> a = ""
>>> b = "second"
>>> (1 and [a] or [b])[0]

''
由于 [a] 是一个非空列表,所以它决不会为假。即使 a 是 0 或者 '' 或者其它假值,列表 [a] 也为真,因为它有一个元素。

到现在为止,这个技巧可能看上去问题超过了它的价值。毕竟,使用 if 语句可以完成相同的事情,那为什么要经历这些麻烦事呢?哦,在很多情况下,你要在两个常量值中进行选择,由于你知道 a 的值总是为真,所以你可以使用这种较为简单的语法而且不用担心。对于使用更为复杂的安全形式,依然有很好的理由要求这样做。例如,在 Python 语言的某些情况下 if 语句是不允许使用的,比如在 lambda 函数中。

进一步阅读

转自:http://woodpecker.org.cn/diveintopython/power_of_introspection/and_or.html

python and 和 or的更多相关文章

  1. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

  2. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  3. Python 小而美的函数

    python提供了一些有趣且实用的函数,如any all zip,这些函数能够大幅简化我们得代码,可以更优雅的处理可迭代的对象,同时使用的时候也得注意一些情况   any any(iterable) ...

  4. JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议

    软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...

  5. 可爱的豆子——使用Beans思想让Python代码更易维护

    title: 可爱的豆子--使用Beans思想让Python代码更易维护 toc: false comments: true date: 2016-06-19 21:43:33 tags: [Pyth ...

  6. 使用Python保存屏幕截图(不使用PIL)

    起因 在极客学院讲授<使用Python编写远程控制程序>的课程中,涉及到查看被控制电脑屏幕截图的功能. 如果使用PIL,这个需求只需要三行代码: from PIL import Image ...

  7. Python编码记录

    字节流和字符串 当使用Python定义一个字符串时,实际会存储一个字节串: "abc"--[97][98][99] python2.x默认会把所有的字符串当做ASCII码来对待,但 ...

  8. Apache执行Python脚本

    由于经常需要到服务器上执行些命令,有些命令懒得敲,就准备写点脚本直接浏览器调用就好了,比如这样: 因为线上有现成的Apache,就直接放它里面了,当然访问安全要设置,我似乎别的随笔里写了安全问题,这里 ...

  9. python开发编译器

    引言 最近刚刚用python写完了一个解析protobuf文件的简单编译器,深感ply实现词法分析和语法分析的简洁方便.乘着余热未过,头脑清醒,记下一点总结和心得,方便各位pythoner参考使用. ...

  10. 关于解决python线上问题的几种有效技术

    工作后好久没上博客园了,虽然不是很忙,但也没学生时代闲了.今天上博客园,发现好多的文章都是年终总结,想想是不是自己也应该总结下,不过现在还没想好,等想好了再写吧.今天写写自己在工作后用到的技术干货,争 ...

随机推荐

  1. HDU 11488 Hyper Prefix Sets (字符串-Trie树)

    H Hyper Prefix Sets Prefix goodness of a set string is length of longest common prefix*number of str ...

  2. 新浪微博开放平台开发-android客户端(1)【转】

    http://www.cnblogs.com/virusswb/archive/2011/08/05/2128941.html 最近不是太忙,花了一些时间学习android的应用开发.经过两个星期的学 ...

  3. 如何得到Sessionid的值

    当用户向一个网站请求第一个页面时,用户会话启动.当第一个页面被请求时,web服务器将asp.net_sessionID  cookie添加进用户的浏览器.可以使用newsession属性探测新会话的启 ...

  4. DEV GridControl 小结(持续添加)

    一.属性: 1.Views OptionsBehavior=>Editable:False  列表不可编辑 OptionsSelection=>EnableAppearanceFocuse ...

  5. HDU 5226 Tom and matrix(组合数学+Lucas定理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5226 题意:给一个矩阵a,a[i][j] = C(i,j)(i>=j) or 0(i < ...

  6. BZOJ 1034: [ZJOI2008]泡泡堂BNB( 贪心 )

    贪心...用最弱的赢最弱的,用最强的赢最强的,否则用最弱的和最强的比... (贴个官方题解:将双方的选手均按从强到弱排序,然后第一次扫描尽可能用当前剩下的选手中能赢对手当前最强选手中最弱的一个去赢得胜 ...

  7. js正则语法

    整数或者小数:^[0-9]+\.{0,1}[0-9]{0,2}$只能输入数字:"^[0-9]*$".只能输入n位的数字:"^\d{n}$".只能输入至少n位的数 ...

  8. tomcat管理员manager app无法进入解决方法

    浏览器输入http://localhost:8080/进入tomcat页面后,点击manager app输入用户名(admin)密码(admin)后页面跳转出现如下错误:备注:tomcat7.0.39 ...

  9. css3 display:box

    想做自适应的流体布局 box很有用 . 还没有得到firefox.Opera.chrome浏览器的完全支持,但可以使用它们的私有属性定义firefox(-moz-).opera(-o-).chrome ...

  10. PGA与SGA

    当用户进程连接到数据库并创建一个对应的会话时,Oracle服务进程会为这个用户专门设置一个PGA区,用来存储这个用户会话的相关内容.当这个用户会话终止时,数据库系统会自动释放这个PAG区所占用的内存. ...