转载

单位元对编程的启发

最近,我在处理一个文本文件,它有三列,分别为文件名,数字,字符串,且其中第一列中有若干重复了的部分,于是我需要把这些重复的行合并起来,即第二列合并为总和,第三列合并为一条新字符串,且用空格分隔。

我一开始想如此合并:

sum = 0 string = '' for duplicate_line in duplicate_lines:     sum += duplicate_line.split()[1]     string = ' '.join(str,  duplicate_line.split()[2] 

但迭代完后 string 并不符合我的期望,它包含了一个 heading space! 这令我想起了抽象代数学上的「单位元」,即 它在某二元运算中,与任意元素运算后,结果的值恒为后者本身 。比如加法中的 0 与任何数字相加,恒返回后者的原值;乘法中的 1 也同理。

于是我们可以说 ' '.join() 作为二元运算符来说, 不存在单位元 。比如 ' '.join([a, b]) 中 b 为任意字符串时,不存在 a 变量能使这函数返回 b 本身,哪怕变量 a 为空字符串时,也会返回包含了一个 heading space 和 b 值的新字符串!就像我上面的代码一样。不过 ''.join() 当然就有单位元即空字符串。

反观 Python 的加法,它就有单位元,即 sum 的初值 0 , 也难怪它和悲剧的 string 君不同,可以安全地返回我期望的值,即可谓「无副作用」。

这启发了我又一条编程规范: 要小心那些没有单位元的函数或运算符,并处理得当 。其实上面合并 string 的代码可以妙用 list comprehension, 回避掉副作用:

' '.join([duplicate_line.split()[2] for duplicate_line in duplicate_lines]) 

举一反三,Python Sequences 的 index 为什么从 0 而不是 1 开始计呢?您倒不如想想另一个问题: Sequences Index 的单位元是什么? 即对 Index 进行二元运算时,加多少就返回原 Index? 当然是 0 了!再看 C 指针,它和 0 相加时就返回原指针,也难怪 C 的 Array Index 和 Python 的 Sequences Index 都从 0 开始,这是为了 当直接把原 Index(甚至 C 的指针即地址)和 Index 初始值(即单位元)相加时,能方便且直接地得到原 Index(甚至 C 的原指针即原地址)。

Written with StackEdit .

原文  http://tech.acgtyrant.com/单位元对编程的启发/
正文到此结束
Loading...