本文几乎涵盖了and和or所有知识点,篇幅较长,一点要静下心来看,学无止境。
1.and和or的含义
既然我们要运用and和or,那么首先就应该知道and与or的意思是什么。你可以把它当作数学里的与运算和或运算。假设a为真命题,b为假命题,那“a与b”是假命题,“a或b”为真命题。
在python中也是一样的意思,如下表:
运算符含义逻辑表达式说明and与运算a and b当 a 和 b 两个表达式都为真时,a and b 的结果才为真,否则为假。or或运算a or b当 a 和 b 两个表达式都为假时,a or b 的结果才是假,否则为真。
2.and和or的用法
python中的逻辑运算符有两种返回值,python运算符除了能操作bool类型表达式,还能操作其他所有类型的表达式。一些初学者可能没了解过运算符操作其他类型的表达式。并且返回的值也不止bool类型。下面我们就来详细了解and与or的两种用法。
- 运算bool类型
操作bool类型表达式的时候就是第一点中表格的用法。
下面我们来举几个例子就明白了:
a = 1>2 and 1<2; print(a) #输出结果为:Falseb = 1>2 or 1<2; print(b) #输出结果为:True12345
这一用法还是比较简单。当操作bool类型时返回值都是bool类型。
- 运算其他类型:
运算其他类型时返回的都是操作表达式的值,如表:
运算符含义逻辑表达式说明and与运算a and b如果 a 为 False,a and b 返回 a 的值,否则返回 b 的计算值。or或运算a or b如果 a 是 True,a or b 返回 a 的值,否则它返回 b 的计算值。
初学者一定不要死板记得套用说明中的运算方法。要知道为什么a为False就返回a的值。在学习其他知识的时候也是这样。
题外话:在学习中,如果你想学精:千万不能只知其然,不知其所以然。一定要知其然,并知其所以然。不然你只能学的好,但是学不精。如果你觉得有的人很厉害,而你根本没那个天赋,达不到别人的高技术,那你们唯一的区别就在于此,就那么简单,加油,你也很棒!
其本质是因为:
在与运算中,一个为假,那整个运算肯定都为假,无论b是真还是假,都不会影响最终的结果,所以返回a的值,如果为真,那后面的b不知是真还是假,所以要继续运算,则返回b的值。
在或运算中,只要有一个为真,那整个运算都为真,所以只要a为真,那不管b是真还是假,最终的结果都是真,所以返回a的值。反之。
这一点是我们后面要讲到的“短路逻辑”的本质。
举例说明:
a = 1b = 0c = "Hello World"d = ""print(a and b) #输出结果为 0print(a or b) #输出结果为 1print(c and d) #输出结果为 "" /(即什么都不输出)print(c or d) #输出结果为 Hello Worldprint(a and c) #输出结果为 1123456789101112
所以从上看来,and和or不仅能操作其他类型表达式,还能混合运算,即不同类型的表达式进行运算。并且返回的值不是bool类型,而是表达式的值。
看到这可能有的初学者就懵了,int,string类型怎么会有false和true之说。
在python中:None、任何数值类型中的0、空字符串“”、空元组()、空列表[]、空字典{}都被当作False,还有自定义类型,如果实现了 __ nonzero __ () 或 __ len __ () 方法且方法返回 0 或False,则其实例也被当作False,其他对象均为True。
所以在逻辑运算符操作其他类型表达式的时候是先以其对象返回的bool值进行运算,然后返回表达式。
注:其他类型也能与bool类型进行运算,且运算规则和此规则一样,将bool类型当作其他类型就行了。
例如:
a = Trueb = False;c = 1d = "Hello World"print(a and c) #输出结果为 1print(b and c) #输出结果为 Falseprint(b or d) #输出结果为 Hello World12345678910
-总结:
- 在逻辑运算符and和or中不仅可以操作bool类型的表达式,还能操作其他类型表达式,返回值也不仅是bool类型,也可以是其他类型。
- 在只进行bool表达式操作时,返回值是bool类型,其运算规则是:
and:a and b, 当 a 和 b 两个表达式都为真时,a and b 的结果才为真,否则为假。
or:a or b, 当 a 和 b 两个表达式都为假时,a or b 的结果才是假,否则为真。 - 在有其他类型参与运算时,返回值是其表达式类型值,其运算规则是:
and :a and b,如果 a 为 False,a and b 返回 a 的值,否则返回 b 的计算值。
or:a or b,如果 a 是 True,a or b 返回 a 的值,否则它返回 b 的计算值。
3.“短路逻辑”
在学习完and和or的含义与用法之后,我们就要来进行“短路逻辑”的用法学习了。
在之前的讲解与例子中,我们操作的只有两个表达式,即 a and b ,a or b。那么要用运算符操作多个表达式又该怎样去算呢,这时,我们就要运用到“短路逻辑”了。
什么是短路逻辑:若and左侧的表达式为false,则短路之后所有的and表达式,直到出现or,则返回and左侧表达式的值继续与or的右侧参与运算。若or左侧的表达式为true,则短路之后所有的表达式,不管是or还是and,直接输出or左侧表达式的值。若 or 的左侧为 False ,或者 and 的左侧为 True 则不能使用短路逻辑。
为了更好的理解“短路逻辑”,我们先用常规思想从左至右来运算一下多个表达式:
result1 = 0 and 10 and 20 and 30 and 40print(result1) # 输出结果为 0#运算:0 and 10 = 0#所以result = 0 and 20 and 30 and 400 and 20 = 0#所以result = 0 and 30 and 400 and 30 = 0#所以result = 0 and 400 and 40 = 0#所以最终结果 :result = 0result2 = 10 or 0 or "" or {} or ()print(result2) #输出结果为 10#运算:10 or 0 = 10#所以result = 10 or "" or {} or ()10 or "" = 10#所以result = 10 or {} or ()10 or {} = 10#所以result = 10 or ()10 or () = 10#所以最终结果 :result = 1012345678910111213141516171819202122232425262728
从上述例子来看,我们从左至右运算的最终结果就是正确结果啊,但是再让我们用这种方法来看看or和and混合运算时的结果:
result = 10 or 0 and 20 and 30print(result) #输出结果为 10#运算:10 or 0 = 10#所以result = 10 and 20 and 3010 and 20 = 20#所以result = 20 and 3020 and 30 = 30#所以最终结果 :result = 30123456789101112
哎,好奇怪啊,怎么运算的结果和输出的结果不一样啊,明明都一步一步来运算的啊,真是奇怪。莫慌莫慌,这是因为啊,在python中,and和or运算时会短路,而这样“短路”现象,必须用我们的“短路逻辑”来运算了。
为了直观的看到在and与or运算时怎么会短路,我们使用方法来使用一下and和or。
先来看看都是and的情况:
def a():print("a")return 0def b():print("b")return 1def c():print("c")return 1def d():print("d")return 1result = a() and b() and c() and d()print("最终返回值:",result)#输出结果为:a最终返回值:01234567891011121314151617181920212223
看见没,为什么a(),b(),c() ,d()都参与了运算,而只打印了a。那是因为在 运算中,a()的值是0,为False,而其后都是and运算符,所以全部被短路,系统根本就没有调用后面的方法参与运算了,所以只打印了a出来。这就是为什么叫“短路”现象。
再来看看都是or的情况:
def a():print("a")return 0def b():print("b")return 1def c():print("c")return 2def d():print("d")return 3result = a() or b() or c() or d()print("最终返回值:",result)#输出结果为:ab最终返回值:1123456789101112131415161718192021222324
a()为False,b()为True,所以 a() or b() = b(),b()为True,那么就要继续参与运算:b() or c() = b() 返回的是True,则第二个or其后所有的表达式都要被短路,注意是第二个or,因为第一个or左侧表达式a()为False,所以还要继续运算,没有短路。也就是从左至右,在哪个or运算到左侧逻辑值为True时,就短路哪个or之后所有的表达式。所以只打印了a,b,最终返回值为b()的值:1。
接下来就要实际运算到and和or都有的情况了:
def a():print("a")return 0def b():print("b")return 1def c():print("c")return 2def d():print("d")return 3def e():print("e")return 0def f():print("f")return 4def g():print("g")return 0def h():print("h")return 5result = a() and b() and c() or d() or e() and g() or h()print("最终返回值:",result)#输出结果为:ad最终返回值: 312345678910111213141516171819202122232425262728293031323334353637383940
千万不要看到这么长就觉得很难,只要你真正理解了短路逻辑的本质,它就是变身器,无论碰到什么怪兽时,你都能变身迪迦奥特曼打败它。当然了,你一定要相信光,相信迪迦。“迪迦!”
我们先进行第一步运算,a() = 0,b() = 1,a() and b() = a() = 1;所以第一个and后的所有and连接但是是下一个or出现之前的表达式都要被短路,也就是b(),c()会被短路。所以打印a但不打印b,c。接着运算:a() or d() = d() = 3or的左侧a为False,所以后面的表达式不会被短路,打印 d ,继续运算:d() or e() = d() =3or的左侧d()为True,后面所有表达式都会被短路了,所以最后的返回值为3。1234567891011
值得注意的是:在有多个and,or连接运算的时候,很多初学者可能有绕懵,认为就只是运算符and,or 两侧的表达式在进行运算,不是的,是and,or两侧的逻辑值进行运算。
例如在上述例子计算d() or e()时,d()是被返回一个最终值在进行运算,也就是在运算过后要把a() and b() and c() or d()看成一个值,再去与后面的e 进行or运算,而不要直接就当作是d()在后面的e进行运算,是因为 a and b and c or d = d()
其实就等同于数学里:(a+b+c)* d,要先算括号里的值,但括号里是算出一个最终值A=a+b+c来,再进行接下来的运算A*d。