這是我在python-ideas上發佈的一些東西,但我認爲這些頗有趣,應該分享給更多的人。python
最近有不少關於合併兩個dict(詞典)的運算符的討論。編程
這促使我思考爲何有些人喜歡運算符,我想起了30多年前與導師Lambert Meertens的一次討論。ide
對於數學家來講,運算符對於他們的思考方式相當重要。咱們來選取一個簡單的操做,好比將兩個數相加,並嘗試研究它的一些行爲。在學習中有迷茫不知如何學習的朋友小編推薦一個學Python的學習q u n 227 -435- 450能夠來了解一塊兒進步一塊兒學習!免費分享視頻資料函數
add(x, y) == add(y, x) (1)性能
式(1)表示了加法的交換律。它一般用運算符來書寫,這使得它更簡潔:學習
x + y == y + x (1a)idea
這彷佛是一個小小的收穫。視頻
如今咱們來考慮一下結合律:對象
add(x, add(y, z)) == add(add(x, y), z) (2)blog
式(2)能夠用運算符重寫:
x + (y + z) == (x + y) + z (2a)
這比式(2)容易理解得多,而且咱們發現括號是多餘的,因此如今咱們能夠這樣寫:
x + y + z (3)
沒有歧義(+ 運算符綁定到左邊仍是右邊並不重要)。
許多其餘定律也能夠很容易的使用運算符來寫。這裏還有一個關於加法恆等元素的例子:
add(x, 0) == add(0, x) == x (4)
相比於
x + 0 == 0 + x == x (4a)
這裏的總的思想就是一旦你學會了這個簡單的表示法,用它們寫的方程就比用函數表示法寫的方程更容易「操做」——就好像咱們的大腦用不一樣的大腦機制來掌握運算符,這是更有效率的方法。
我認爲,使用運算符編寫的公式更容易被「視覺化」處理就與此有關: 它們利用了大腦的視覺處理機制,而這一機制在很大程度上是在潛意識中運做的,而且它會告訴大腦的意識部分它看到了什麼(好比,「椅子」而不是「幾塊木頭連在一塊兒」)。函數符號在咱們的大腦中則必須走一條不一樣的路徑,這是無心識的(它與內容的閱讀和理解有關,這是在比視覺處理更晚的年齡段才學會/訓練的)。
當你將多個運算符結合在一塊兒時,視覺處理的功能就會變得很是明顯。例如,考慮一下分配律:
mul (n,add(x, y)) == add(mul (n, x) mul (n, y)) (5)
這寫起來很惱火,我相信一開始你是不會看到這個規律的(或者至少你不會馬上看到它,若是我沒有提到這是分配律的話)。
與下式比較:
n * (x + y) == n * x + n * y (5a)
注意,這裏也使用了相對的運算符優先級。一般數學家們會把它寫得更緊湊:
n(x+y) == nx+ny (5b)
可是,遺憾的是,目前這超出了Python解析器的能力。
運算符表示法的另外一個很是強大的方面是,能夠方便地將它們應用於不一樣類型的對象。例如,定律(1)到(5)在x、y和z是相同大小的向量,而n是標量(用0向量代替字面量「0」)時也適用,若是它們是矩陣(一樣,n必須是一個標量)也適用。
你能夠這樣處理不一樣域中的對象。例如,上面的定律(1)到(5)也適用於函數(n也是一個標量)。
經過明智地選擇運算符,數學家們能夠運用他們的視覺大腦來幫助他們更好地進行數學研究: 他們會更快地發現新的有趣的定律,由於有時黑板上的符號就會跳到你面前,給你提供一條通往難以捉摸的數學證實的道路。
如今,編程並不徹底等同於數學,但咱們都知道可讀性很重要,這就是Python中運算符重載的做用。一旦你內化了運算符具備的簡單屬性,使用+號進行字符串或列表鏈接將比純OO表示法更具可讀性,上面(2)和(3)解釋了(部分程度上)爲何是這樣。
固然,這樣作絕對有可能作過火——而後你就會使用Perl。但我認爲,那些指出「已經有辦法作到這一點」的人忽略了一點,即真正理解這一點是比較容易的:
d = d1 + d2
和下面相比:
d = d1.copy ()
d.update(d2) #修正:這一行以前是錯誤的
這不只僅是少了幾行代碼的事: 第一種形式容許咱們使用咱們的視覺處理,以幫助咱們更快的看到它的意思,而且不會影響咱們大腦的其餘部分(例如,這些部分可能已經被跟蹤d1和d2的意思佔據)。
固然,任何事情都是有代價的。你必須學習運算符,而且在應用於不一樣對象類型時必須學習它們的屬性。(數學中也是如此——對於數字,x*y == y*x,可是這個屬性不適用於函數或矩陣; 另外一方面,正如結合律同樣, x+y == y+x適用於全部狀況。)
「可是性能呢?」我聽見你這樣問。好問題。在我看來,可讀性第一,性能第二。在基本的例子(d = d1 + d2)中,與使用update的兩行代碼版本相比,沒有性能損失,並且可讀性明顯提升。我能想到不少狀況,性能差別可有可無,但可讀性是最重要的,對我來講,這是默認的假設(即便在Dropbox——咱們最重要的性能代碼已經用醜陋的Python或Go重寫過了)。對於少數性能相當重要的狀況,很容易將運算符版本轉換爲其餘版本——*一旦你確認了這是頗有必要的*(多是經過分析得出d的)。