前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >对 python 中变量值交换的一些思考

对 python 中变量值交换的一些思考

作者头像
波罗学
发布2019-07-31 11:46:29
8160
发布2019-07-31 11:46:29
举报
文章被收录于专栏:码神路漫漫

在编程中,一旦提到变量值的交换,脑海中最先浮现的做法就是引入一个临时变量作为媒介来做,来看看具体的实现。

解决方案

先假设有两个变量x、y,如下:

代码语言:javascript
复制
x = 10
y = 20

常见方案,定义一个临时变量作为媒介,实现变量值的交换。实现如下:

代码语言:javascript
复制
t = x
x = y
y = t

pythonic,对于这种需求其实python为我们提供了一种更方便的解决方案。

代码语言:javascript
复制
x, y = y, x

从代码上就可以直观的理解此处的意图,即实现x与y变量值的交换。 到这里都非常容易理解,但是接下来我们需要思考一下:此写法性能如何?为什么可以如此便捷地就是实现了变量值交换?

性能比较

虽然写法简洁方便,但是是否已损耗性能为代价呢?定义两个函数:

代码语言:javascript
复制
def swap1():
    x = 1
    y = 2
    t = x 
    x = y
    y = t

def swap2():
    x = 1
    y = 2
    x, y = y, x
复制代码

为了更好的看出性能差异,循环调用分别调用两函数100次(需要在ipython中执行):

swap1耗时38µs

代码语言:javascript
复制
%time a = [swap1() for _ in range(100)]

结果如下:

代码语言:javascript
复制
CPU times: user 31 µs, sys: 7 µs, total: 38 µs
Wall time: 67 µs

swap2耗时18µs

代码语言:javascript
复制
%time a = [swap2() for _ in range(100)]

结果如下:

代码语言:javascript
复制
CPU times: user 18 µs, sys: 0 ns, total: 18 µs
Wall time: 21 µs

可以看出pythonic的写法比简单粗暴的引入新的辅助变量要快很多。写法如此简洁而且性能高,何乐而不为呢。

这有一篇文章 python面试值交换变量值,从底层解释了两种方式性能差异原因。swap2 通过 ROT_TWO 指令交换两个变量的值肯定比执行 LOAD_FAST+STORE_FAST 两条指令效率高。

注:对于两个变量的交换,其实并没有用到元组,可以看看这个视频

多些思考

那么下面再思考一个问题:为什么python可以用这种写法来赋值呢?

看一些赋值运算符右边的表达式,即 y, x,这实际在python中称为元组的数据结构。我们可以看到赋值表达式左边是 x, y,那么为什么元组可以直接赋值给 x,y 呢?

此处利用了python的一个特性,即任何序列(或可迭代的对象)都可以通过简单的赋值操作分解为单独的变量。我们再来看一个例子:

代码语言:javascript
复制
name, age, mobile = 'polo', 30, '15312210823'

执行以上代码便可将name赋值为polo,age赋值为30,phone赋值为15312210823。

延伸扩展

除了以上这种简单序列的拆解,python同样支持其他更复杂的场景,下面来看看多层嵌套变量的分解,例子最直观:

代码语言:javascript
复制
school_name, (student_name, stduent_age, stduent_sex) = '致远中学', ('polo', 18, 'M')

也可以支持不定长序列的灵活分解,比如现在有一个班级已排序的学生成绩列表,如下:

代码语言:javascript
复制
scores = [21, 34, 36, 56, 60, 75, 76, 81, 83, 86, 86, 89, 90, 95, 98, 99]

我们的目标获取成绩最大、最小和其他学生的成绩列表,直接通过序列的分解便可快速得到需要的数据:

代码语言:javascript
复制
min_score, *other_scores, max_score = scores

这里引入了一种新的写法,*表达式变量轻松分解出中间的可迭代对象并赋值给other_scores,同时将开头和结束的对象分别赋值给min_score和max_score。

看到这里感觉序列分解似乎有点类似于正则表达式的模式匹配。

总结

虽然只是小小的变量值的交换,但本质也是由需求和语言自身特性决定的。学会一些必要的技巧,将会帮助我们写出更高质量的代码。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年05月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解决方案
  • 性能比较
  • 多些思考
  • 延伸扩展
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档