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中在對數字或者字符串比較時,這些相同值的數字或字符串引用的就應該是同一個地址空間了】

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