这是我在python-ideas上发布的一些东西,但我认为这些很有趣,应该分享给更多的人。

最近有很多关于合并两个dict(词典)的运算符的讨论。

这促使我思考为什么有些人喜欢运算符,我想起了30多年前与导师Lambert Meertens的一次讨论。

对于数学家来说,运算符对于他们的思考方式至关重要。我们来选取一个简单的操作,比如将两个数相加,并尝试研究它的一些行为。

add(x, y) == add(y, x) (1)

式(1)表示了加法的交换律。它通常用运算符来书写,这使得它更简洁:

x + y == y + x (1a)

这似乎是一个小小的收获。

现在我们来考虑一下结合律:

add(x, add(y, z)) == add(add(x, y), z) (2)

式(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的)。

Python之父:为什么操作符很有用?的更多相关文章

  1. ipython, 一个 python 的交互式 shell,比默认的python shell 好用得多,支持变量自动补全,自动缩进,支持 bash shell 命令,内置了许多很有用的功能和函数

    一个 python 的交互式 shell,比默认的python shell 好用得多,支持变量自动补全,自动缩进,支持 bash shell 命令,内置了许多很有用的功能和函数. 若用的是fish s ...

  2. Python 之父撰文回忆:为什么要创造 pgen 解析器?

    花下猫语: 近日,Python 之父在 Medium 上开通了博客,并发布了一篇关于 PEG 解析器的文章(参见我翻的 全文译文).据我所知,他有自己的博客,为什么还会跑去 Medium 上写文呢?好 ...

  3. Python 之父再发文:构建一个 PEG 解析器

    花下猫语: Python 之父在 Medium 上开了博客,现在写了两篇文章,本文是第二篇的译文.前一篇的译文 在此 ,宣布了将要用 PEG 解析器来替换当前的 pgen 解析器. 本文主要介绍了构建 ...

  4. Python 之父的解析器系列之五:左递归 PEG 语法

    原题 | Left-recursive PEG grammars 作者 | Guido van Rossum(Python之父) 译者 | 豌豆花下猫("Python猫"公众号作者 ...

  5. Python 之父为什么嫌弃 lambda 匿名函数?

    Python 支持 lambda 匿名函数,其扩展的 BNF 表示法是lambda_expr ::= "lambda" [parameter_list] ":" ...

  6. 100多个很有用的JavaScript函数以及基础写法大集合

    100多个很有用的JavaScript函数以及基础写法大集合 1.document.write("");为 输出语句2.JS中的注释为//3.传统的HTML文档顺序是:docume ...

  7. 今日推荐:10款在 Web 开发中很有用的占位图片服务

    设计网站时,将要使用的图像在一开始通常还不存在,这个时候布局是最重要的.然而,图像的尺寸通常是预先设置,实用一些占位图像可以帮助我们更好地预览和分析布局. 如今,有免费的占位图片自动生成工具可以使用, ...

  8. Unix / 类 Unix shell 中有哪些很酷很冷门很少用很有用的命令?(转)

    著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:孙立伟 链接:http://www.zhihu.com/question/20140085/answer/14107336 ...

  9. Python之父重回决策层

    在Guido van Rossum(吉多·范罗苏姆)卸任BDFL(“终身仁慈独裁者”)一职半年多之后,Python社区迎来了新的治理新方案:指导委员会模式,而经过投票Guido van Rossum也 ...

随机推荐

  1. NumPy学习_02 ndarray基本操作

    1.算术运算符 它们只用于位置相同的元素之间,即为元素级的运算. 所得到的运算结果组成一个新的数组. 不用编写循环即可对数据执行批量运算.(矢量化) import numpy as np # 创建一个 ...

  2. python基础之Day20part1

    一.hash算法 什么是hash? 类似工厂加工的过程,传bytes串,经过运算返回字符 hash相当于工厂,传给hash算法的内容是原材料,hash值为产品 为何用hash? hash三大特性: 1 ...

  3. linux学习第十八天 (Linux就该这么学)

    今天讲了23章节,OPENLDAP安装配置,感觉好难 ,不过考试测试,CA也没有了,主要还讲了数据库mariadb,安装,配置,使用,基本的数据库管理,还讲了,网络安装系统,我暂时先不写其它了,上传图 ...

  4. vb编程中的is是什么意思??

    在select case 语句中可以使用关系运算符大于>小于<等于=等关系运算符,需要用关键字IS和TO.用个例子来说明:Private Sub Command1_Click()Dim a ...

  5. union: git command

    # switch one tag # warning: if do that, can't commit any change git clone $project_path git checkout ...

  6. 关于TypeError: strptime() argument 1 must be str, not bytes解析

    关于TypeError: strptime() argument 1 must be str, not bytes解析   在使用datetime.strptime(s,fmt)来输出结果日期结果时, ...

  7. 山东省ACM多校联盟省赛个人训练第六场 poj 3335 D Rotating Scoreboard

    山东省ACM多校联盟省赛个人训练第六场 D Rotating Scoreboard https://vjudge.net/problem/POJ-3335 时间限制:C/C++ 1秒,其他语言2秒 空 ...

  8. Promise实战AJAX封装

    一.利用Promise的知识,对最开始的ajax的例子进行一个简单的封装: var url = 'xxx'; // 封装一个get请求的方法 function request(url){ return ...

  9. pycharm无法使用ctrl+c/v复制粘贴的问题

    最近在使用pycharm的时候发现不能正常使用ctrl+c/v进行复制粘贴,也无法使用tab键对大段代码进行整体缩进.后来发现是因为安装了vim插件的问题,在setting里找到vim插件,取消勾选即 ...

  10. 使用rsync实现不同Linux服务器间目录同步

    实现目标:    A 服务器上 /opt/web 目录,与B服务器上 /opt/web目录实现同步.即:B主动与A进行同步.   OS: Reaht AS4   A Server  192.168.1 ...