这是我在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的)。