python中n个元素进行==操作的问题

以下内容首发于我的个人博客网站:
http://riun.xyz


事情的前戏是今天在做一个python的小练习:利用generator生成杨辉三角时遇到一个小问题,期间由于一个错误足足折磨了好几个小时。

杨辉三角大致是这样:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wFR1ASCJ-1590762944525)(https://s1.ax1x.com/2020/03/25/8jEjyV.jpg)]

要求输出成这样的形式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8U4Sh77Y-1590762944531)(https://s1.ax1x.com/2020/03/25/8jVVOK.jpg)]

我的代码是这样:

# 练习:利用generator生成器打印杨辉三角
def triangles(n):
    # n = 10

    preL = []
    nL = [x*0 for x in range(n)]

    for i in range(n): # 外循环,控制循环几次,即 有几行
        for j in range(i+1): # 内循环,控制每行循环几次,即每行有几个元素
            if j == 0 | j == i: # 此处应将 | 换为 or
                nL[j] = 1
            else:
                nL[j] = preL[j-1] + preL[j]

        preL = nL[:i+1]
        #print(preL)
        yield preL

#yangh(5)

yh = triangles(10)
for x in yh:
    print(x)

我的思路是在内循环生成nL列表,生成的时候对每行第1个元素和最后一个元素单独处理,均赋值为1。中间的元素取上面的列表的第j-1和第j个元素之和。

但是输出来总是不对:

8jVfh9.jpg

由于公司项目需要,我刚开始学python,很多语法还不熟,可劲折腾了好久才发现问题。

原来我把内层循环中处理临界值的判断语句搞错了。就是if j == 0 | j == i:这句。

我的本意是 j0 或者 ji,就是当循环到本行的第一个 或者 最后一个元素时处理。

但是错用了 按位或| 运算符,我之前想用 || 来着,可是写了后报错,就换成|,不报错了我就以为是对的。没想到还是错了,应该用 逻辑运算符or。上面代码将 | 换为 or就完全正确了


重点就是我在排查的时候进行了如下输出:

i = 1
j = 0
print(j==0 | j==i) # True | False = False
print(True | False) # True | False = True
>>> False
>>> True

心想,嗯?j0应该是 True,ji应该是False。那么第一个表达式就是True | False,这不是和第二个一样吗,为什么结果还不一样?

后来想到运算符优先级的事情,发现原来 | 比 == 优先级高。

所以第一个输出其实是这样:

print(0==0 | 0==1)

先运算 |

print(0==0==1)

就是这个式子,重点来了!

我本来想的是从右向左运算?那么先运算 01,为False,再计算0False,为True吧

但是万万没想到这个式子结果居然输出False!

惊了~!,这是为什么啊?

难道是我中间过程有问题?

接着我又试着找证据证明我的过程是对的:

print(0==0==1)
print(0==False)
print(True==1)
>>> False
>>> True
>>> True

看着这个结果我陷入了沉思:

第二第三行输出告诉我:0False 是 True ; 1True 也是 True
那第一个表达式001
如果从左向右算:
00 是True ; 然后 True == 1 是 True 啊,但是表达式结果是False
如果从右向左算:
0
1 是False; 然后0==False 还是True啊,但是表达式结果是False

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5YJdJU8c-1590762944538)(https://s1.ax1x.com/2020/03/25/8jRW9K.jpg)]

我尼玛人都傻了,!》? 这是什么奇奇怪怪的东西?

然后我问了几个同学,这到底是怎么比较的啊,有的不知道,有的也理解不了。后来一个室友无意间说了句”他可能是同时算的“

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ya8AOixX-1590762944542)(https://s1.ax1x.com/2020/03/25/8jymBq.jpg)]

我心里一惊,欸,不是吧?好像有道理欸。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZwuDVsQm-1590762944545)(https://s1.ax1x.com/2020/03/25/8j2qlF.jpg)]

然后我做了实验:

print((0==0)==1)
>>> True

8jRMp8.jpg

居然输出True!!!!!

这样就对了,00是True,True1还是True。结果对上了!

那么就是说print(0==0==1)还真是同时算的,计算三个元素是否相等!

我又做了如下输出:

print(False==False==True)
>>> False

果然,几个元素连着进行 == 运算,就是判断这几个元素是否一致啊!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e75u0zdN-1590762944550)(https://s1.ax1x.com/2020/03/25/8jRdpT.jpg)]

接着机智的我又想到了Java里会是怎样。我知道Java中

System.out.println(0==0==1);

这样是错误的,因为无论从那边算起,都会出现int和boolean进行比较的情况出现。所以无法比较,加括号也不行。将int强转为boolean也不行,因为无法强转。

所以我就试了试这样:

System.out.println(false==false==true);
>>> true

输出结果是true,和python中不同。

也就是说Java中几个元素进行 == 运算,是从右向左进行运算,先计算falsetrue,结果是false,再计算falsefalse,结果才是true。

总结

python中,几个元素进行==运算,比较的是几个元素(的值)是否都相等,只要有一个不等,就是False,全部相等,才是True。

java中对几个元素进行==运算,是向普通运算符那样,从右向左依次比较,得到true或者false,再与前一个比较,最后返回结果。

【上面说python中==比较的是值,还没有充分证明,但我感觉是这样的。如果说比较的是地址值的话,那么python中在对数字或者字符串比较时,这些相同值的数字或字符串引用的就应该是同一个地址空间了】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章