Python 笔试集(1):关于 Python 链式赋值的坑
前言
Python 的链式赋值是一种简易型批量赋值语句,一行代码即可为多个变量同时进行赋值。
例如:
x = y = z = 1
链式赋值是一种非常优雅的赋值方式,简单、高效且实用。但同时它也是一个危险的糖衣炸弹,值得我们引起关注。
面试题:求链式赋值语句中变量 x 的值?
x = [1, 2, 3, 4, 5]
i = 0
i = x[i] = 3
- 如果你有过 C 语言的编程经验,那么你的思维习惯可能会让你得出这样的结果:x[0] 被赋值为 3,然后 i 再被赋值为 3,所以变量 x 的值为
[3, 2, 3, 4, 5]。 - 但实际上正确的答案却是:变量 i 首先被赋值为 3,然后 x[3] 再被赋值为3,所以最终变量 x 的值为
[1, 2, 3, 3, 5]。
从上述结果的表现可以看出二者的区别为:C 语言的赋值顺序是 自右往左* 依次进行的,而 Python 则相反。*
造成这种表征区别的本质原因是由于 C 语言是一种「值语义」类型语言,而 Python 是「对象语义」类型语言。
值语义类型编程语言
值语义指使用系统标准的拷贝方式将一个源对象拷贝成为目标对象后,源对象与目标对象之间毫无关系,彼此独立存在,改变互不影响。
从这一特性出发, C 语言的赋值语句被设计成了具有返回值的表达式,如此才能够保证在链式赋值中所有的对象最终都是彼此独立的。
例如:
x = (y = 1)
表达式 y = 1 在将数值 1 赋值给对象 y 之后返回了数值 1 ,最后再将返回的数值 1 赋值给对象 x。虽然两次赋值操作的数值都是 1,但实际上 x 和 y 对象在内存中的地址是不相同的,所以 x 和 y 彼此独立。
对象语义类型编程语言
对象语义,也称为引用语义。指使用系统标准的拷贝方式将一个源对象拷贝成为目标对象后,源对象与目标对象之间依然共享底层资源,对任意一方的改变都将影响到另一方。
由于不需要像 C 语言那般要求对象之间的独立性。所以,Python 的赋值语句就仅仅是一条语句,而非表达式,也就不存在返回值。在 Python 的定义中,表达式是由操作符(Operator)连接而成的语句,但等号 = 并不属于 Python 的操作符,而是分隔符(Delimiters)。所以下列语句在 Python 中是非法的。
In : x = (y = 1)
File "<ipython-input-6-f6b416f5f895>", line 1
x = (y = 1)
^
SyntaxError: invalid syntax
因为 y = 1 并没有返回值,所以最后执行的是将 “没有返回值” 赋值给了变量 x,显然这样的语义是不存在意义的。
最后
从使用的角度来说,我们只需要简单的记住 Python 的链式赋值顺序是 自左往右 的即可。但更重要的是,通过该面试题我们了解到了 Python 实现的语义类型为对象语义,以及对象语义和值语义的区别。这非常有助于我们以后理解、解决或避免 Python 大多数隐含的坑。
Python 笔试集(1):关于 Python 链式赋值的坑的更多相关文章
- Python 笔试集(4):True + True == ?
目录 目录 前文列表 面试题True Ture 布尔值 布尔类型是特殊的整数类型 前文列表 Python 笔试集:什么时候 i = i + 1 并不等于 i += 1? Python 笔试集(1):关 ...
- python学习(二十一) Python 中的链式赋值
Python的链式赋值如下:
- Python特色的序列解包、链式赋值、链式比较
一.序列解包 序列解包(或可迭代对象解包):解包就是从序列中取出其中的元素的过程,将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列变量中. 一般情况下要解包的序列包含的元素个数必须与你在等 ...
- 第4.7节 Python特色的序列解包、链式赋值、链式比较
一.序列解包 序列解包(或可迭代对象解包):解包就是从序列中取出其中的元素的过程,将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列变量中. 一般情况下要解包的序列包含的元素个数必须与你在等 ...
- Python链式赋值执行顺序及执行方式的证明
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 在<关于Python链式赋值的赋值顺序问题& ...
- 关于Python链式赋值的赋值顺序问题
在<第4.7节 Python特色的序列解包.链式赋值.链式比较>一文中,老猿这样介绍的: 链式赋值是用一行语句将多个变量赋值为同一个值,语法如下: 变量1=变量2=变量n=赋值表达式 该语 ...
- pyhton链式赋值在可变类型/不可变类型上的区别以及其本质
关于链式赋值的一些注意点: a=[]b=[]x=y=[]print(a==b) #Trueprint(x==y) #Trueprint(a is b) #Falseprint(x is y) #Tru ...
- DataFrame 链式赋值
在运行以下Python代码时,Pandas抛出SettingWithCopyWarning警告: row_data = df_pred.loc[key] row_data['col'] = new_v ...
- python和go对比字符串的链式处理
一.什么是链式处理 对数据的操作进行多步骤的处理称为链式处理,链式处理器是一种常见的编程设计,链式处理的开发思想将数据和操作拆分,解耦,让开发者可以根据自己的技术优势和需求,进行系统开发,同时将自己的 ...
随机推荐
- kali 下安装 vmtools
网上的教程都是默认路径下的,kali是定制版本的,路径不同,所以首先要找到media下安装包的路径,然后进入该路下,将安装包复制到想要的路径下,并解压缩到想要的路径下,剩下的就跟网上的差不多了,即找到 ...
- java 约瑟夫问题
题目: 给定一个数组及数组的长度,另外给定一个数m,从数组的第一个元素出发,数到第m个元素出列(如果到最后则回到第一个元素).出列元素的值作为m的新值,从出列元素的下一元素继续开始数下去,直到所有元素 ...
- Android 静态代码分析工具
简评: 作者在文中提到的三个静态代码分析工具不是互相替代的关系,各有各的侧重点,如果有需要完全可以同时使用. 静态代码分析是指无需运行被测代码,仅通过分析或检查源程序的语法.结构.过程.接口等来检查程 ...
- web渗透系列--信息收集
信息收集对于渗透测试前期来说是非常重要的,因为只有我们掌握了目标网站或目标主机足够多的信息之后,我们才能更好地对其进行漏洞检测.正所谓,知己知彼百战百胜! 信息收集的方式可以分为两种:主动和被动. 主 ...
- 【LeetCode】堆 heap(共31题)
链接:https://leetcode.com/tag/heap/ [23] Merge k Sorted Lists [215] Kth Largest Element in an Array (无 ...
- 用 Webpack 解决应用性能问题
1. 影响页面加载时长的 Top3 因素 页面初载时,加载大量 JavaScript 脚本: 页面初载时,加载大量 CSS 文件: 页面初载时,加载大量网络资源: 页面加载的越久,页面不可交互的时间就 ...
- 【POJ2152】Fire
题目大意:给定一棵 N 个节点的无根树,点有点权,边有边权,现需要选出一个点集,满足树上任意一个点到该点集的距离不超过该点的给定值,求选出点集点权的最小值是多少. 题解:可以发现,对于以 i 为根的子 ...
- mysql安装配置和启动
MySQL数据库安装配置和启动 1,下载MySQL 打开MySQL的官网www.mysql.com,发现有一个DOWNLOADS 点击它,进入到MySQL的下载页面,在页面的底部有一个MySQL ...
- git提示Please enter a commit message to explain why this merge is necessary
Please enter a commit message to explain why this merge is necessary. 请输入提交消息来解释为什么这种合并是必要的(提交信息) gi ...
- 百度地图api的简单应用(二):轻量级路径规划
同上篇的原理,我们还是输入url,返回json文件. 而由图可见,路径规划返回的json文件内容可能会很多.杂: 因此后续的处理与上篇略有不同. import json import requests ...