变量赋值的几种形式细节

本文解释python中变量赋值的形式,并解释一些细节。后面还有一篇文章解释python中按引用赋值的文章。

python中变量赋值的几种形式。

x = "long" # (1).基本形式

x, y = "long", "shuai" # (2).元组对应赋值

[x, y] = ["long", "shuai"] # (3).列表对应赋值

a, b, c, d = "long" # (4).序列赋值

a, *b = 'long' # (5).解包赋值

a = b = "long" # (6).多目标赋值

a += 3 # (7).二元赋值表达式

((a, b), c) = ('lo','ng') # (8).嵌套赋值序列

注意:python的数值是不可变对象,无法在原处修改数据,所以不支持自增、自减。

a++

++a

a--

--b

其中(1)-(3)无需过多解释,唯一需要注意的是,当使用逗号的时候,python总会临时或永久地建立成tuple来保存元素,所以x, y = "long", "shuai"在内部完全等价于(x, y) = ("long", "shuai")。

实际上,列表元素也可以赋值给元组,或者元组赋值给列表,只要两边的序列元素个数能对应,无所谓左右两边的序列类型:

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

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

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

>>> [x,y] = [1,2]

>>> (x,y) = 'ab'

>>> [x,y] = 'ab'

对于(4)赋值方式,是序列赋值的行为,在python中,只要是序列,都可以这样赋值。正如这里的变量赋值情况等价于:

a = "l"

b = "o"

c = "n"

d = "g"

如果换成其它的序列也一样。例如:

a, b, c, d = ("shell","perl","php","python")

a, b, c, d = ["shell","perl","php","python"]

但是变量和序列中的元素必须一一对应。如果变量名与元素个数不同,则会报错,除非只有一个变量名,这表示将整个序列赋值给这个变量。

如果想要将序列中的元素赋值给不等的变量,可以考虑先将序列进行切片。

>>> str='long'

>>> a, b, c = list(str[:2]) + [str[2:]]

>>> a,b,c

('l', 'o', 'ng')

(5)的赋值方式则正好是让变量名少于元素个数的方式。这种赋值形式称为序列解包(下文会专门解释这种赋值方式),多出来的元素会全部以列表的方式赋值给最后一个变量名。正如这里等价于:

a="l"

b=["o", "n", "g"]

下面两种赋值方式得到的结果是一样的,a是字符串,b是列表,b都包含3个元素:

a, *b = ("shell","perl","php","python")

a, *b = ["shell","perl","php","python"]

赋值的结果:

shell

['perl', 'php', 'python']

(6)的赋值方式等价于:

b = "long"

a = b

python赋值时,总是先计算"="右边的结果,然后将结果按照赋值方式赋值给"="左边的变量。所以,这里的过程是先将"long"赋值给变量b,再将b赋值给变量a。

因为总是先计算右边,所以交换变量非常的方便。

a, b = "a", "b"

# 交换:

a, b = b, a

# 交换结果:

a = "b"

b = "a"

(7)的赋值方式a += 3在结果上等价于a = a + 3,在其它语言中这两种赋值方式是完全等价的,但在python中这种增强赋值的方式要比后者更高效率些,为什么效率要高一些,下文会稍作解释。在很大程度上来说,Python中只要是简化的形式,基本上都比更复杂的等价形式效率更高。

(8)的赋值方式((a, b), c) = (‘lo‘, ‘ng‘)是将序列进行嵌套序列赋值,将‘lo‘赋值给元组(a, b),‘ng‘赋值给c,元组又进一步赋值a=‘l‘, b=‘o‘。这种赋值方式在python中很好用,特别是在表达式中赋值的时候,比如for循环和函数参数:

for (a, b, c) in [(1, 2, 3), (4, 5, 6)]:...

for ((a, b), c) in [((1, 2), 3), ((4, 5), 6)]:...

def f(((a, b), c)):...

f(((1, 2), 3))

关于序列解包

在前面简单介绍了一下序列解包:

a, *b = 'long'

当使用一个*前缀变量的时候,表示将序列中对应的元素全部收集到一个列表中(注意,总是一个列表),这个列表名为*开头的那个变量名。*号可以出现在任意位置处,只要赋值的时候能前后对应位置关系即可。

注意其中的几个关键字:序列、对应的元素、列表

序列意味着可以是列表、元组、字符串等等

列表意味着只要收集不报错,赋值给解包变量的一定是一个列表

对应的元素意味着可能收集到0或任意个元素到列表。

不管如何,收集的结果总是列表,只不过可能是空列表或者只有一个元素的列表。

例如:

L = ['aa','bb','cc','dd']

a, *b = L # a='aa',b=['bb','cc','dd']

a, b, *c = L # a='aa',b='bb',c=['cc','dd']

a,*b,d = L # a='aa',d='dd',b=['bb','cc']

*a,d = L # a=['aa','bb','cc'],d='dd'

a,b,c,*d = L # a='aa',b='bb',c='cc',d=['dd']

a,b,c,d,*e = L # a='aa',b='bb',c='cc',d='dd',e=[]

两个注意事项:

因为序列解包是根据元素位置来进行赋值的,所以不能出现多个解包变量

如果将序列直接赋值给单个解包变量时(即没有普通变量),这个解包变量必须放在列表或元组中

a,*b,c,*d = L # 错误

*a = L # 错误

[*a] = L # 正确

(*a) = L # 正确

之所以单个解包变量时必须放在元组或变量中,看下面两个等价的例子就很容易理解了:

a, *b = L

(a, *b) = L

最后,序列解包是切片的便捷替代方式。能用序列解包的,都能用切片来实现,但切片要输入额外的各种字符。例如:

a,b,c = L[0],L[1],L[2:]

a,b,*c = L

需要注意,解包返回的一定是列表,但序列切片返回的内容则取决于序列的类型。例如下面元组的切片返回的是元组,而不是列表:

>>> T=('aa','bb','cc','dd')

>>> a,b,c = T[0],T[1],T[2:]

>>> a,b,c

('aa', 'bb', ('cc', 'dd'))

二元赋值表达式

python支持类似于a += 3这种二元表达式。比如:

a += 3 -> a = a + 3

a -= 3 -> a = a - 3

a *= 3 -> a = a * 3

...

在python中的某些情况下,这种二元赋值表达式可能比普通的赋值方式效率更高些。原因有二:

二元赋值表达式中,a可能会是一个表达式,它只需计算评估一次,而a = a + 3中,a要计算两次。

对于可变对象,可以直接在原处修改得到修改后的值,而普通的一元赋值表达式必须在内存中新创建一个修改后的数据对象,并赋值给变量

第一点无需解释。关于第二点,看下面的例子:

L = [1,2,3]

L = L + [4] # (1):慢

L += [4] # (2):快

L.append(4) # (3):快,等价于(2)

L = L + [5,6] # (4):慢

L += [5,6] # (5):快

L.extend([5,6]) # (6):快,等价于(5)

对于上面(1)和(4)的一元赋值表达式,先取得L,然后创建一个新的列表对象,将L的数据拷贝到新列表对象中,并将4或5,6放进新列表对象,最后赋值给L。这个过程中涉及到了几个步骤:新分配内存、内存中列表数据拷贝、放入新数据。所以,效率较差,特别是L比较大的时候,拷贝L也是高开销的动作。

而(2)(3)是等价的,(5)(6)也是等价的,它们都是直接在内存中的原始列表处修改,不会有拷贝操作,新建的数据对象仅仅只是一个元素。

所以,使用二元赋值表达式通常可以作为可变对象赋值的一种优化手段。

原文地址:https://www.cnblogs.com/f-ck-need-u/p/10122962.html

python变量的使用_python变量赋值的几种形式细节相关推荐

  1. python赋值语句格式_Python中变量和变量赋值的几种形式

    动态类型的语言 python是动态类型的语言,不需要声明变量的类型. 实际上,python中的变量仅仅只是用来保存一个数据对象的地址.无论是什么数据对象,在内存中创建好数据对象之后,都只是把它的地址保 ...

  2. python变量赋值方式_python变量和变量赋值的几种形式

    动态类型的语言 python是动态类型的语言,不需要声明变量的类型. 实际上,python中的变量仅仅只是用来保存一个数据对象的地址.无论是什么数据对象,在内存中创建好数据对象之后,都只是把它的地址保 ...

  3. python变量和变量赋值的几种形式

    动态类型的语言 python是动态类型的语言,不需要声明变量的类型. 实际上,python中的变量仅仅只是用来保存一个数据对象的地址.无论是什么数据对象,在内存中创建好数据对象之后,都只是把它的地址保 ...

  4. c语言给数组赋值的3种形式

    c语言给数组赋值的3种形式 在C语言中,对数组进行赋值的三种形式 推荐学习:C语言视频教程 1.通过循环的形式 即:数组名[下标] 对数组的元素进行依次赋值 #includeint main(){in ...

  5. C语言之数组(数组赋值的三种形式)

    在C语言中,对数组进行赋值的三种形式 1.通过循环的形式     即:数组名[下标]      对数组的元素进行依次赋值 #include <stdio.h> int main() {in ...

  6. c语言 多字节赋值给数组,c语言给数组赋值的3种形式

    c语言给数组赋值的3种形式 在C语言中,对数组进行赋值的三种形式 推荐学习:C语言视频教程 1.通过循环的形式 即:数组名[下标] 对数组的元素进行依次赋值 #include int main() { ...

  7. c#数组赋初值_c语言给数组赋值的3种形式

    c语言给数组赋值的3种形式 在C语言中,对数组进行赋值的三种形式 1.通过循环的形式 即:数组名[下标] 对数组的元素进行依次赋值#include int main() { int i; int a[ ...

  8. python变量详解_Python 变量详解[学习 Python 必备基础知识][看此一篇就够了]

    您的"关注"和"点赞",是信任,是认可,是支持,是动力...... 如意见相佐,可留言. 本人必将竭尽全力试图做到准确和全面,终其一生进行修改补充更新. 1 P ...

  9. python变量区分大小写吗_Python变量名是不是区分大小写的

    Python变量名是不是区分大小写的 发布时间:2020-11-10 14:13:23 来源:亿速云 阅读:95 作者:小新 Python变量名是不是区分大小写的?这个问题可能是我们日常学习或工作经常 ...

最新文章

  1. 面对疫情,飞书线上办公室,让我们换一种方式重聚!
  2. 每个设计师应该阅读的8本书
  3. XXL-RPC v1.3.2,分布式服务框架
  4. PLSQL Developer 插入中文 乱码问题,如图 这个是由于oracle服务器端字符编码 和 Oracle 客户端 字符编码不一致引起的。 检查Oracle服务器端字符编码,用 sel
  5. python各个解释器的用途-python解释器有哪些?
  6. python 寻找比目标字母大的最小字符
  7. hdu 1255(线段树+离散化)
  8. Centos eclipse打开文件自动退出
  9. python-描述符的分类
  10. vrrp路由协议实验
  11. 【转】iOS编译OpenSSL静态库(使用脚本自动编译)
  12. Socket网络编程--Libev库学习(3)
  13. 编译自定义的主题theme
  14. 解决Jenkins上git出现的“ERROR: Error fetching remote repo ‘origin‘”问题
  15. 常用数据接口汇总,百度、谷歌、头条、微博指数,高校名单,疫情数据...
  16. (Matlab实现)CNN卷积神经网络图片分类
  17. 蓝湖能导入html文件么,axure怎么导入蓝湖
  18. 立创开源 | 恒温加热台
  19. 《软件技术学研会-技术培训》第0章 操作系统安装
  20. 用1元钱买到原价万元的电脑是什么体验?

热门文章

  1. 5G 空口信令分析指导书
  2. 游戏数值策划入门介绍
  3. 新颖的自我介绍_精选简单新颖的自我介绍
  4. HDU5142 NPY and arithmetic progression BestCoder Round #23 1002
  5. AWD线下攻防平台搭建
  6. 已损坏打不开您应该推出磁盘映像
  7. Python爬虫:输入公司名称,爬取企查查网站中的公司信息
  8. 三、项目进度管理(输入/工具与技术/输出)
  9. 雷电2接口_厉害!跟Type-C长得一毛一样的雷电3,原来区别这么大,别搞混了
  10. C/C++常用函数总结以及在ubuntu和vs中运行