在 C/C++/Java 等等语言中,整型变量的自增或自减操做是标配,它们又可分为前缀操做(++i 和 --i)与后缀操做(i++ 和 i--),彼此存在着一些细微差异,各有不一样的用途。python
这些语言的使用者在接触 Python 时,可能会疑惑为何它不提供 ++ 或 -- 的操做呢?在我前不久发的《Python的十万个为何?》里,就有很多同窗在调查问卷中表示了对此话题感兴趣。ide
Python 中虽然可能出现 ++i 这种前缀形式的写法,可是它并无“++”自增操做符,此处只是两个“+”(正数符号)的叠加而已,至于后缀形式的“++”,则彻底不支持(SyntaxError: invalid syntax)。函数
本期“Python为何 ”栏目,咱们将会从两个主要的角度来回答:Python 为何不支持 i++ 自增语法? (PS:此处自增指代“自增和自减”,下同)spa
首先,Python 固然能够实现自增效果,即写成i += 1
或者 i = i + 1
,这在其它语言中也是通用的。翻译
虽然 Python 在底层用了不一样的魔术方法(__add__()
和 __iadd__()
)来完成计算,但表面上的效果彻底相同。设计
因此,咱们的问题能够转化成:为何上面的两种写法会赛过 i++,成为 Python 的最终选择呢?code
当咱们定义i = 1000
时,不一样语言会做出不一样的处理:视频
int i = 1000
)会申请一块内存空间,并给它“绑定”一个固定的名称 i,同时写入一个可变的值 1000。在这里,i 的地址以及类型是固定的,而值是可变的(在必定的表示范围内)i = 1000
)也会申请一块内存空间,可是它会“绑定”给数字 1000,即这个 1000 的地址以及类型是固定的(immutable),至于 i,只是一个名称标签贴在 1000 上,自身没有固定的地址和类型因此当咱们令 i “自增”时(i = i + 1),它们的处理是不一样的:对象
打一个不太恰当的比方:C 中的 i 就像一个宿主,数字 1000 寄生在它上面;而 Python 中的 1000 像个宿主,名称 i 寄生在它上面。C 中的 i 与 Python 中的 1000,它们则寄生在底层的内存空间上……内存
还能够这样理解:C 中的变量 i 是一等公民,数字 1000 是它的一个可变的属性;Python 中的数字 1000 是一等公民,名称 i 是它的一个可变的属性。
有了以上的铺垫,咱们再来看看 i++,不难发现:
Python 若支持 i++,其操做过程要比 C 的 i++ 复杂,并且其含义也再也不是“令数字增长1”(自增),而是“建立一个新的数字”(新增), 这样的话,“自增操做符”(increment operator)就名存实亡了。
Python 在理论上能够实现 i++ 操做,但它就必须从新定义“自增操做符”,还会令有其它语言经验的人产生误解,不如就让你们直接写成i += 1
或者 i = i + 1
好了。
C/C++ 等语言设计出 i++,最主要的目的是为了方便使用三段式的 for 结构:
for(int i = 0; i < 100; i++){ // 执行 xxx }
这种程序关心的是数字自己的自增过程,数字作加法与程序体的执行相关联。
Python 中没有这种 for 结构的写法,它提供了更为优雅的方式:
for i in range(100): # 执行 xxx my_list = ["你好", "我是Python猫", "欢迎关注"] for info in my_list: print(info)
这里体现了不一样的思惟方式,它关心的是在一个数值范围内的迭代遍历,并不关心也不须要人为对数字作加法。
Python 中的可迭代对象/迭代器/生成器提供了很是良好的迭代/遍历用法,可以作到对 i++ 的彻底替代。
例如,上例中实现了对列表内值的遍历,Python 还能够用 enumerate() 实现对下标与具体值的同时遍历:
my_list = ["你好", "我是Python猫", "欢迎关注"] for i, info in enumerate(my_list): print(i, info) # 打印结果: 0 你好 1 我是Python猫 2 欢迎关注
再例如对于字典的遍历,Python 提供了 keys()、values()、items() 等遍历方法,很是好用:
my_dict = {'a': '1', 'b': '2', 'c': '3'} for key in my_dict.keys(): print(key) for key, value in my_dict.items(): print(key, value)
有了这样的利器,哪里还有 i++ 的用武之地呢?
不只如此,Python 中基本上不多使用i += 1
或者 i = i + 1
,因为存在着随处可见的可迭代对象,开发者们很容易实现对一个数值区间的操做,也就不多有对于某个数值做累加的诉求了。
因此,回到咱们开头的问题,其实这两种“自增”写法并无胜出 i++ 多少,只由于它们是通用型操做,又不须要引入新的操做符,因此 Python 才延续了一种基础性的支持。真正的赢家实际上是各类各样的可迭代对象!
稍微小结下:Python 不支持自增操做符,一方面是由于它的整数是不可变类型的一等公民,自增操做(++)若要支持,则会带来歧义;另外一方面主要由于它有更合适的实现,便可迭代对象,对遍历操做有很好的支持。
若是你以为本文分析得不错,那你应该会喜欢这些文章:
四、Python 为何没有 main 函数?为何我不推荐写 main 函数?
写在最后:本文属于“Python为何”系列(Python猫出品),该系列主要关注 Python 的语法、设计和发展等话题,以一个个“为何”式的问题为切入点,试着展示 Python 的迷人魅力。部分话题会推出视频版,请在 B 站收看,观看地址:视频地址
公众号【Python猫】, 本号连载优质的系列文章,有Python为何系列、喵星哲学猫系列、Python进阶系列、好书推荐系列、技术写做、优质英文推荐与翻译等等,欢迎关注哦。