第一句子大全,网罗天下好句子,好文章尽在本站!

Python 为什么只需一条语句“a b=b a” 就能直接交换两个变量?

时间:2023-01-28

但是无论行业,哪个领域,想要熟练使用Python,就必须掌握Python的基础知识

友情提示:本文共有 2242 个字,阅读大概需要 5 分钟。

Python是一款使用方便,易上手的工具,我们平常在工作中经常会用到,而且同时也是一款功能强大的编程语言,被广泛应用于数据分析、web开发、人工智能等行业。但是无论行业,哪个领域,想要熟练使用Python,就必须掌握Python的基础知识。

以下文章来源于:微信公众号Python猫

作者: 豌豆花下猫

从接触 Python 时起,我就觉得 Python 的元组解包(unpacking)挺有意思,非常简洁好用。

最显而易见的例子就是多重赋值,即在一条语句中同时给多个变量赋值:

>>> x, y = 1, 2

>>> print(x, y) # 结果:1 2

在此例中,赋值操作符“=”号的右侧的两个数字会被存入到一个元组中,即变成 (1,2),然后再被解包,依次赋值给“=”号左侧的两个变量。

如果我们直接写x = 1,2 ,然后打印出 x,或者在“=”号右侧写成一个元组,就能证实到这一点:

>>> x = 1, 2

>>> print(x) # 结果:(1, 2)

>>> x, y = (1, 2)

>>> print(x, y) # 结果:1 2

一些博客或公众号文章在介绍到这个特性时,通常会顺着举一个例子,即基于两个变量,直接交换它们的值:

>>> x, y = 1, 2

>>> x, y = y, x

>>> print(x, y) # 结果:2 1

一般而言,交换两个变量的操作需要引入第三个变量。道理很简单,如果要交换两个杯子中所装的水,自然会需要第三个容器作为中转。

然而,Python 的写法并不需要借助中间变量,它的形式就跟前面的解包赋值一样。正因为这个形式相似,很多人就误Python 的变量交换操作也是基于解包操作。

但是,事实是否如此呢?

我搜索了一番,发现有人试图回答过这个问题,但是他们的回答基本不够全面。(当然,有不少是错误的答案,还有更多人只是知其然,却从未想过要知其所以然)

先把本文的答案放出来吧:Python 的交换变量操作不完全基于解包操作,有时候是,有时候不是!

有没有觉得这个答案很神奇呢?是不是闻所未闻?!

到底怎么回事呢?先来看看标题中最简单的两个变量的情况,我们上dis 大杀器看看编译的字节码:

上图开了两个窗口,可以方便比较“a,b=b,a”与“a,b=1,2”的不同:

“a,b=b,a”操作:两个 LOAD_FAST 是从局部作用域中读取变量的引用,并存入栈中,接着是最关键的 ROT_TWO 操作,它会交换两个变量的引用值,然后两个 STORE_FAST 是将栈中的变量写入局部作用域中。“a,b=1,2”操作:第一步 LOAD_CONST 把“=”号右侧的两个数字作为元组放到栈中,第二步 UNPACK_SEQUENCE 是序列解包,接着把解包结果写入局部作用域的变量上。很明显,形式相似的两种写法实际上完成的操作并不相同。在交换变量的操作中,并没有装包和解包的步骤!

ROT_TWO 指令是 CPython 解释器实现的对于栈顶两个元素的快捷操作,改变它们指向的引用对象。

还有两个类似的指令是 ROT_THREE 和 ROT_FOUR,分别是快捷交换三和四个变量(摘自:ceval.c 文件,最新的 3.9 分支):

预定义的栈顶操作如下:

查看官方文档中对于这几个指令的解释,其中 ROT_FOUR 是 3.8 版本新加的:

ROT_TWOSwaps the two top-most stack items.ROT_THREELifts second and third stack item one position up, moves top down to position three.ROT_FOURLifts second, third and forth stack items one position up, moves top down to position four.New in version 3.8.

CPython 应该是以为这几种变量的交换操作很常见,因此才提供了专门的优化指令。就像 [-5,256] 这些小整数被预先放到了整数池里一样。

对于更多变量的交换操作,实际上则会用到前面说的解包操作:

截图中的 BUILD_TUPLE 指令会将给定数量的栈顶元素创建成元组,然后被 UNPACK_SEQUENCE 指令解包,再依次赋值。

值得一提的是,此处之所以比前面的“a,b=1,2”多出一个 build 操作,是因为每个变量的 LOAD_FAST 需要先单独入栈,无法直接被组合成 LOAD_CONST 入栈。也就是说,“=”号右侧有变量时,不会出现前文中的 LOAD_CONST 一个元组的情况。

最后还有一个值得一提的细节,那几个指令是跟栈中元素的数量有关,而不是跟赋值语句中实际交换的变量数有关。看一个例子就明白了:

分析至此,你应该明白前文中的结论是怎么回事了吧?

我们稍微总结一下:

Python 能在一条语句中实现多重赋值,这是利用了序列解包的特性Python 能在一条语句中实现变量交换,不需引入中间变量,在变量数少于 4 个时(3.8 版本起是少于 5 个),CPython 是利用了 ROT_* 指令来交换栈中的元素,当变量数超出时,则是利用了序列解包的特性。序列是 Python 的一大特性,但是在本文的例子中,CPython 解释器在小小的操作中还提供了几个优化的指令,这绝对会超出大多数人的认知

本文如果对你有帮助,请点赞收藏《Python 为什么只需一条语句“a b=b a” 就能直接交换两个变量?》,同时在此感谢原作者。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。
相关阅读
效仿婴儿学习语言 MIT打造了一个具有观察力的AI模型

效仿婴儿学习语言 MIT打造了一个具有观察力的AI模型

...和动词的位置。而在计算机领域,语言学习是语法和语义分析器需要执行的任务。训练它们需要使用使用人工标注的句子,这些标注提供了句子结构和词语含义的信息。语法分析器对于网页搜索、自然语言数据库查询、Alexa和Siri...

2023-01-28 #经典句子

SCI仿写和降重神器 直接英语写SCI!

SCI仿写和降重神器 直接英语写SCI!

...。而科研必备神器“句解霸”可以解决这些困惑。1句子分析器功能分析页面网址:http://www.en998.com/sentence/?sid=d94(文末点击“阅读原文”可直达,同时在该页面也可以切换到降重功能)在句子分析器功能这块,我输入一个有错误...

2020-10-31 #经典句子

自然语言处理库spaCy号称最快句法分析器

自然语言处理库spaCy号称最快句法分析器

...前支持20多种语言的标记。它具有世界上速度最快的句法分析器,用于标签的卷积神经网络模型,解析和命名实体识别以及与深度学习整合。它是在MIT许可下发布的商业开源软件。spaCy项目由@honnibal和@ines维护,虽然无法通过电子...

2023-01-28 #经典句子

良心推荐——这三款冷门英语学习app不容错过

良心推荐——这三款冷门英语学习app不容错过

...这款app还内置考研真题库,大大方便考研同学!NO.2 句子分析器 Pro这款软件主打英语文本语法分析。只要输入英语句子,这款app就会自动分析出句子结构,并且提供相关语法知识的讲解。热爱读外刊却又对长句十分头疼的同学绝...

2022-11-19 #经典句子

父母如何帮助孩子发展语言?

父母如何帮助孩子发展语言?

...的声音以及婴儿的“咿呀学语”都是在不断刺激言语听觉分析器和言语运动分析器的发展。婴儿只要能和父母正常的互动以及其他类型的声音,在这两方面的发展就不会存在不足。单词字期(1-1.5岁)是指一个单词常常表示一个...

2007-06-09 #经典句子

什么是自然语言处理(NLP)?

什么是自然语言处理(NLP)?

...词性提取和标记化来分析单词背后的意图。IBM Watson音频分析器。这个基于云计算的解决方案旨在用于社交监听、聊天机器人集成和客户服务监控。它可以分析客户帖子中的情绪和语气,并监控客户服务电话和聊天对话。谷歌云...

2023-06-11 #经典句子

各刷五大数据集新高 创新工场两篇论文入选 ACL 2020

各刷五大数据集新高 创新工场两篇论文入选 ACL 2020

...和业界广泛知名的斯坦福大学的CoreNLP工具和伯克利句法分析器在这些数据集上的性能虽然还不错,但是如果把他们的这些深层句法信息进一步加到我们的模型里面,进行去粗取精,就能把里面比较好的信息通过加权的方式甄选...

2023-11-28 #经典句子

扩展命名实体识别API及其在语言教育中的应用

扩展命名实体识别API及其在语言教育中的应用

...st.i.kyoto-u.ac.jp/EN/?JUMAN)自动生成的,JUMAN是一个日语词法分析器。词向量是通过一个采用日语维基百科文本训练的word2vec模型获得的。我们希望LSTM模型可以记忆训练数据模式,并在很多情况下应用于CRF-SVM方法。对于上下文无关...

2023-11-25 #经典句子

创新工场两篇论文入选ACL 2020 将中文分词数据刷至新高

创新工场两篇论文入选ACL 2020 将中文分词数据刷至新高

...度超过了斯坦福大学的 CoreNLP 工具,和伯克利大学的句法分析器。即使是在与CTB词性标注规范不同的UD数据集中,该模型依然能吸收不同标注带来的知识,并使用这种知识,得到更好的效果。该模型在所有数据集上均超过了之前...

2023-11-28 #经典句子