Crossin的编程教室

标题: 【Python 第51课】 and-or技巧 [打印本页]

作者: crossin先生    时间: 2013-8-22 23:45
标题: 【Python 第51课】 and-or技巧
今天介绍一个python中的小技巧:and-or

看下面这段代码:
  1. a = "heaven"
  2. b = "hell"
  3. c = True and a or b
  4. print c
  5. d = False and a or b
  6. print d
复制代码
输出:
heaven
hell

结果很奇怪是不是?
表达式从左往右运算,1和"heaven"做and的结果是"heaven",再与"hell"做or的结果是"heaven";0和"heaven"做and的结果是0,再与"hell"做or的结果是"hell"。
抛开绕人的and和or的逻辑,你只需记住,在一个bool and a or b语句中,当bool条件为真时,结果是a;当bool条件为假时,结果是b。
有学过c/c++的同学应该会发现,这和bool?a:b表达式很像。

有了它,原本需要一个if-else语句表述的逻辑:
  1. if a > 0:
  2.     print "big"
  3. else:
  4.     print "small"
复制代码
就可以直接写成:
  1. print (a > 0) and "big" or "small"
复制代码
然而不幸的是,如果直接这么用,有一天你会踩到坑的。和c语言中的?:表达式不同,这里的and or语句是利用了python中的逻辑运算实现的。当a本身是个假值(如0,"")时,结果就不会像你期望的那样。

比如:
  1. a = ""
  2. b = "hell"
  3. c = True and a or b
  4. print c
复制代码
得到的结果就是"hell"。因为""和"hell"做or的结果是"hell"。

所以,and-or真正的技巧在于,确保a的值不会为假。最常用的方式是使 a 成为 [a] 、 b 成为[ b ] ,然后使用返回值列表的第一个元素:
  1. a = ""
  2. b = "hell"
  3. c = (True and [a] or [b])[0]
  4. print c
复制代码
由于[a]是一个非空列表,所以它决不会为假。即使a是0或者''或者其它假值,列表[a]也为真,因为它有一个元素。

在两个常量值进行选择时,and-or会让你的代码更简单。但如果你觉得这个技巧带来的副作用已经让你头大了,没关系,用if-else可以做相同的事情。不过在python的某些情况下,你可能没法使用if语句,比如lambda函数中,这时候你可能就需要and-or的帮助了。

什么是lambda函数?呵呵,这是python的高阶玩法,暂且按住不表,以后有机会再说。

#==== Crossin的编程教室 ====#
微信ID:crossincode
论坛:http://crossin.me
QQ群:312723402

面向零基础初学者的编程课
每天5分钟,轻松学编程



作者: SH40Z1HU1    时间: 2013-8-23 00:10
真是挺巧妙的。
作者: xiaotong125    时间: 2013-8-23 09:58
果断支持大神的无私奉献
作者: Victor    时间: 2013-8-29 08:13
支持一下~
作者: fl0w    时间: 2013-9-24 10:26
good
作者: michael    时间: 2013-10-2 01:15

作者: michael    时间: 2013-10-2 01:25
>>> def f (x): return x**2
>>> print f(8)
64
>>>
>>> g = lambda x: x**2
>>> print g(8)
64
作者: crossin先生    时间: 2013-10-2 10:37
michael 发表于 2013-10-2 01:25
>>> def f (x): return x**2
>>> print f(8)
64



作者: musray    时间: 2014-6-5 08:09
这一课碉堡了。我再也无法按耐住这颗潜水的心。
不过我在我的python2.7.5上实验了一下,得出的结果如下:

>>> a = ''
>>> a and 'Hell'
''
>>>
作者: crossin先生    时间: 2014-6-5 13:52
musray 发表于 2014-6-5 08:09
这一课碉堡了。我再也无法按耐住这颗潜水的心。
不过我在我的python2.7.5上实验了一下,得出的结果如下:

空字符是False
所以 ‘’ and ‘Hell’ 时,在前半段就直接可以得出结果了,于是就是a的结果
作者: 脑子有音乐    时间: 2014-6-27 20:45
a = ""
b = "hell"
c = (True and [a] or [b])[0]
print c
--------------------------------
[0] 加了是空白 不加是['']
老师的本意是要我们看到a的值吗?
作者: crossin先生    时间: 2014-6-28 16:58
脑子有音乐 发表于 2014-6-27 20:45
a = ""
b = "hell"
c = (True and [a] or )[0]

是的
作者: liu-pengfei    时间: 2014-9-26 00:45
本帖最后由 liu-pengfei 于 2014-9-26 00:48 编辑

好像挺有意思的。不过这段话中,
比如:
复制代码
得到的结果就是"hell"。因为""和"hell"做and的结果是"hell"。
有,因为""和"hell"做and的结果是"hell"。,and应该是改为or吧?

作者: crossin先生    时间: 2014-9-26 10:42
liu-pengfei 发表于 2014-9-26 00:45
好像挺有意思的。不过这段话中,
比如:
  • a = ""

  • 嗯,对
    作者: 草办    时间: 2015-12-11 14:01
    get

    作者: 周末晒被子    时间: 2015-12-17 17:05
    本帖最后由 周末晒被子 于 2015-12-17 17:19 编辑

    先生,

    a = ""
    b = "hell"
    c = True and a or b  #因为""和"hell"做and的结果是"hell"
    print c

    您说,因为""和"hell"做and的结果是"hell",但是应该是,因为""和"hell"做or的结果是"hell"吧?
    因为"hell"在这段代码就只跟在or之后啊~

    作者: 周末晒被子    时间: 2015-12-17 17:27
    crossin先生 发表于 2014-6-5 13:52
    空字符是False
    所以 ‘’ and ‘Hell’ 时,在前半段就直接可以得出结果了,于是就是a的结果 ...

    表示对这个回复看不懂,其实是对 and or ,这整个运算过程不懂。
    我能判断 变量之间比如 a、b, and or 之后会得出True还是False(也就是第6课的知识),但是不知道会输出哪个变量,a还是b。
    作者: crossin先生    时间: 2015-12-17 22:15
    周末晒被子 发表于 2015-12-17 17:05
    先生,

    a = ""

    你说的对,我已经改了。楼上也说到这里的问题
    作者: crossin先生    时间: 2015-12-17 22:16
    周末晒被子 发表于 2015-12-17 17:27
    表示对这个回复看不懂,其实是对 and or ,这整个运算过程不懂。
    我能判断 变量之间比如 a、b, and or  ...

    你可以试试不同值 and 和 or 的结果,会有些理解
    但这个其实有点太过技巧性了,真正编程最好别这么用
    作者: 妙舞汉宫人    时间: 2016-7-29 16:09
    为什么c = (True and [a] or [b])[0]最后需要有[0]?什么意思啊?

    作者: crossin先生    时间: 2016-7-30 22:51
    妙舞汉宫人 发表于 2016-7-29 16:09
    为什么c = (True and [a] or )[0]最后需要有[0]?什么意思啊?

    因为这里构造了[a]和[b ]两个list,用[0]是为了取得其中的元素。
    这个方法其实实际开发中几乎不会用,不用太在意。
    作者: baoxinru    时间: 2017-6-9 17:14
    这个实在太绕了
    作者: YanDong    时间: 2017-8-27 11:31
    老夫这个潜水的心,再也按捺不住啦,楼主好人,好人一生平安!!!




    欢迎光临 Crossin的编程教室 (https://bbs.crossincode.com/) Powered by Discuz! X2.5