点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

在 C/C++/Java 等等语言中,整型变量的自增或自减操作是标配,它们又可分为前缀操作(++i 和 --i)与后缀操作(i++ 和 i--),彼此存在着一些细微差别,各有不同的用途。

这些语言的使用者在接触 Python 时,可能会疑惑为什么它不提供 ++ 或 -- 的操作呢?在我前不久发的《Python的十万个为什么?》里,就有不少同学在调查问卷中表示了对此话题感兴趣。

Python 中虽然可能出现 ++i 这种前缀形式的写法,但是它并没有“++”自增操作符,此处只是两个“+”(正数符号)的叠加而已,至于后缀形式的“++”,则完全不支持(SyntaxError: invalid syntax)。

本期“Python为什么”栏目,我们将会从两个主要的角度来回答:Python 为什么不支持 i++ 自增语法?(PS:此处自增指代“自增和自减”,下同)

首先,Python 当然可以实现自增效果,即写成i+=1或者i=i+1,这在其它语言中也是通用的。

虽然 Python 在底层用了不同的魔术方法(__add__()__iadd__())来完成计算,但表面上的效果完全相同。

所以,我们的问题可以转化成:为什么上面的两种写法会胜过 i++,成为 Python 的最终选择呢?

1、Python 的整数是不可变类型

当我们定义i = 1000时,不同语言会作出不同的处理:

  • C 之类的语言(写法 int i = 1000)会申请一块内存空间,并给它“绑定”一个固定的名称 i,同时写入一个可变的值 1000。在这里,i 的地址以及类型是固定的,而值是可变的(在一定的表示范围内)

  • Python(写法i = 1000)也会申请一块内存空间,但是它会“绑定”给数字 1000,即这个 1000 的地址以及类型是固定的(immutable),至于 i,只是一个名称标签贴在 1000 上,自身没有固定的地址和类型

所以当我们令i“自增”时(i=i+1),它们的处理是不同的:

  • C 之类的语言先找到 i 的地址上存的数值,然后令它加 1,操作后新的数值就取代了旧的数值

  • Python 的操作过程是把 i 指向的数字加 1,然后把结果绑定到新申请的一块内存空间,再把名称标签 i “贴”到新的数字上。新旧数字可以同时存在,不是取代关系

打一个不太恰当的比方:C 中的 i 就像一个宿主,数字 1000 寄生在它上面;而 Python 中的 1000 像个宿主,名称 i 寄生在它上面。C 中的 i 与 Python 中的 1000,它们则寄生在底层的内存空间上……

还可以这样理解:C 中的变量 i 是一等公民,数字 1000 是它的一个可变的属性;Python 中的数字 1000 是一等公民,名称 i 是它的一个可变的属性。

有了以上的铺垫,我们再来看看i++,不难发现:

  • C 之类的语言,i++ 可以表示 i 的数字属性的增加,它不会开辟新的内存空间,也不会产生新的一等公民

  • Python 之类的语言,i++ 如果是对其名称属性的操作,那样就没有意义了(总不能按字母表顺序,把 i 变成 j 吧);如果理解成对数字本体的操作,那么情况就会变得复杂:它会产生新的一等公民 1001,因此需要给它分配一个内存地址,此时若占用 1000 的地址,则涉及旧对象的回收,那原有对于 1000 的引用关系都会受到影响,所以只能开辟新的内存空间给 1001

Python 若支持 i++,其操作过程要比 C 的 i++ 复杂,而且其含义也不再是“令数字增加1”(自增),而是“创建一个新的数字”(新增),这样的话,“自增操作符”(increment operator)就名不副实了。

Python 在理论上可以实现 i++ 操作,但它就必须重新定义“自增操作符”,还会令有其它语言经验的人产生误解,不如就让大家直接写成i += 1或者 i = i + 1好了。

2、Python 有可迭代对象

C/C++ 等语言设计出 i++,最主要的目的是为了方便使用三段式的 for 结构:

for(int i = 0; i < 100; i++){// 执行 xxx
}

这种程序关心的是数字本身的自增过程,数字做加法与程序体的执行相关联。

Python 中没有这种 for 结构的写法,它提供了更为优雅的方式:

for i in range(100):# 执行 xxxmy_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 不支持自增操作符,一方面是因为它的整数是不可变类型的一等公民,自增操作(++)若要支持,则会带来歧义;另一方面主要因为它有更合适的实现,即可迭代对象,对遍历操作有很好的支持。

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

Python 为什么不支持 i++ 自增语法,不提供 ++ 操作符?相关推荐

  1. Python 为什么不支持 i++ 自增语法,不提供 ++ 操作符

    在 C/C++/Java 等等语言中,整型变量的自增或自减操作是标配,它们又可分为前缀操作(++i 和 --i)与后缀操作(i++ 和 i--),彼此存在着一些细微差别,各有不同的用途. 这些语言的使 ...

  2. Python 为什么不支持 i++ 自增语法

    .Python 的整数是不可变类型 当我们定义i = 1000 时,不同语言会作出不同的处理: C 之类的语言(写法 int i = 1000)会申请一块内存空间,并给它"绑定"一 ...

  3. python为什么不能自动语法_Python 为什么不支持 i++ 自增语法,不提供 ++ 操作符?...

    在 C/C++/Java 等等语言中,整型变量的自增或自减操作是标配,它们又可分为前缀操作(++i 和 --i)与后缀操作(i++ 和 i--),彼此存在着一些细微差别,各有不同的用途. 这些语言的使 ...

  4. python自增_Python 为什么不支持 i++ 自增语法,不提供 ++ 操作符?

    文章来源: Python猫 作者:豌豆花下猫 在 C/C++/Java 等等语言中,整型变量的自增或自减操作是标配,它们又可分为前缀操作(++i 和 --i)与后缀操作(i++ 和 i--),彼此存在 ...

  5. c++提供的可有效分配对象空间的运算符是_Python 为什么不支持 i++ 自增语法,不提供 ++ 操作符?

    在 C/C++/Java 等等语言中,整型变量的自增或自减操作是标配,它们又可分为前缀操作(++i 和 --i)与后缀操作(i++ 和 i--),彼此存在着一些细微差别,各有不同的用途. 这些语言的使 ...

  6. Python 为什么不支持 switch 语句?

    " 阅读本文大概需要 10 分钟. " 在这篇文章里,我们会聊一聊为什么 Python 决定不支持 switch 语句. 为什么想要聊这个话题呢? 主要是因为 switch 在其它 ...

  7. 掉进悬崖的小白,捡到python基础秘籍,学习第一周——语法基础,小游戏,无脑循环

    掉进悬崖的小白,捡到python基础秘籍,学习第一周--语法基础,小游戏,无脑循环 人生苦短,我用python 语言的种类: 语言的发展: 什么是python 搭建 Python开发环境: 集成开发环 ...

  8. Python 3.10来了,switch语法终于出现

    开发者(KaiFaX) 面向全栈工程师的开发者专注于前端.Java/Python/Go/PHP的技术社区 来源:机器之心 正文 不用再自己琢磨如何实现 switch 功能了. 对于从事数据科学和人工智 ...

  9. python学习笔记(一)基础语法 — 参考创客智造

    安装pycharm的我在一篇博客里面写过,很简单,我这里就不多写了. 如果在编译器里面想要输出中问的话,需要吧将编码格式改成UFT-8,如何更改呢? #!/usr/bin/python #-*-cod ...

最新文章

  1. SQL Server 性能相关文章 BY GEERT VANHOVE
  2. 查找数组中第二个最小元素
  3. 如何避开购买灯具的9大误区?
  4. 分发 WxWidgets 应用程序
  5. html4的语法,HTML——语法
  6. php无get报错,php $_get报错怎么办
  7. php 正则匹配静态资源,Struts2 配置静态资源文件不经过Strut处理(正则匹配)
  8. android targetapi版本低,我的Android进阶之旅------Android中高低API版本兼容使用@TargetApi或者@SuppressLint(NewApi)...
  9. python工厂模式 简书_[Python设计模式] 01 - 简单工厂模式
  10. PYTHON解析XML的多种方式效率对比实测
  11. 跨域问题深入理解以及解决办法
  12. oracle 数据管理,Oracle深入浅出之数据管理
  13. POJ3461 HDU1686 Oulipo题解
  14. python的浮点数_python 浮点数 转 整数python函数每日一讲 - all()
  15. Quartz Job
  16. 《JavaScript权威指南第7版》第3章 类型、值和变量
  17. 专网视频会议直播系统整合部署方案附拓扑图
  18. 大连最快的dns服务器设置,大连联通50m宽带,本地dns
  19. 阿里云ECS服务器退订
  20. Joel谈优秀软件开发-摘录

热门文章

  1. AI假新闻满天飞,打假神器GROVER帮你看清一切
  2. 10万人的1000万张图像,微软悄然删除最大公开人脸数据集
  3. 每天导航超4亿公里,百度地图整合AI功能
  4. 京东金融晒 “打黑成绩单”:一年内避免用户损失上亿元
  5. Spring Boot 太重,Vert.x 真香!
  6. 为什么不建议在 MySQL 中使用 UTF-8?
  7. “���”引发的线上事故
  8. 关于机器学习模型的可解释性算法!
  9. 工业界AI项目落地的繁琐过程
  10. 统计学习圣经!经典教材《统计学习导论》Python版