python变量和变量赋值的⼏种形式
动态类型的语⾔
python是动态类型的语⾔,不需要声明变量的类型。
实际上,python中的变量仅仅只是⽤来保存⼀个数据对象的地址。⽆论是什么数据对象,在内存中创建好数据对象之后,都只是把它的地址保存到变量名中。所以变量名是类型⽆关的,但它指向的值是类型相关的,可以是数值、字符串、列表、函数、类、对象等等。这些内存对象中都⾄少包含3部分:对象类型、对象的引⽤计数(⽤来判断改对象是否可被垃圾回收器回收)、对象的值。
因此,a = 3中,变量名a保存的是数据对象3的地址,之后可以为其赋值⼀个字符串a = “hello”,这时a保存的是"hello"字符串的地址。在这个类型改变的过程中,a仅仅只是修改了⼀下地址⽽已。
变量的命名风格
python中的变量命名时只能包含数字、⼤⼩写字母、下划线这三种类型的字符,并且数字不能是⾸字符。
还有⼀些有特殊意义的变量命名⽅式(⽬前这些内容了解即可):
1. 前缀并后缀双下划线的变量,如__name__,这种类型的变量在python中有特殊意义,属于对象的内置属性,以后学了类和对象就知
道了
2. 单下划线前缀的变量,如_x,这类变量不会被from ModuleName import *的⽅式导⼊
3. 双下划线前缀的变量,如_x,这类变量是类的本地变量或称为类的私有变量,它会扩展成_classname_x
除此之外,还有约定俗成的命名⽅式:
1. 常量以全⼤写字符表⽰
2. 普通变量、函数名、⽅法名都以⼩写字母开头命名
3. 模块名、包名以全⼩写字母命名
4. 类名以⼤写字母开头
因为只是约定俗成,所以没有强制限制。
变量赋值的⼏种形式细节
本⽂解释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")。vb程序设计基础知识
实际上,列表元素也可以赋值给元组,或者元组赋值给列表,只要两边的序列元素个数能对应,⽆所谓左右两边的序列类型:
>>>(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"]
但是变量和序列中的元素必须⼀⼀对应。如果变量名与元素个数不同,则会报错,除⾮只有⼀个变量名,这表⽰将整个序列赋值给这个变量。
如果想要将序列中的元素赋值给不等的变量,可以考虑先将序列进⾏切⽚。
啊哈c编译器>>>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=[]
两个注意事项:
onblur relate
1. 因为序列解包是根据元素位置来进⾏赋值的,所以不能出现多个解包变量
2. 如果将序列直接赋值给单个解包变量时(即没有普通变量),这个解包变量必须放在列表或元组中
a,*b,c,*d = L    # 错误
*a = L            # 错误withnolock用法
[*a]= L          # 正确
(*a)= L          # 正确
之所以单个解包变量时必须放在元组或变量中,看下⾯两个等价的例⼦就很容易理解了:
a,*b = L
(a,*b)= L
最后,序列解包是切⽚的便捷替代⽅式。能⽤序列解包的,都能⽤切⽚来实现,但切⽚要输⼊额外的各种字符。例如:
a,b,c = L[0],L[1],L[2:]
a,b,*c = L
需要注意,解包返回的⼀定是列表,但序列切⽚返回的内容则取决于序列的类型。例如下⾯元组的切⽚返回的是元组,⽽不是列表:
'''
python基础教程电子书15
遇到问题没⼈解答?⼩编创建了⼀个Python学习交流QQ:531509025
寻有志同道合的⼩伙伴,互帮互助,⾥还有不错的视频学习教程和PDF电⼦书!
'''
>>> T=('aa','bb','cc','dd')
>>> a,b,c = T[0],T[1],T[2:]
jsp四种状态管理
>>> 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中的某些情况下,这种⼆元赋值表达式可能⽐普通的赋值⽅式效率更⾼些。原因有⼆:
1. ⼆元赋值表达式中,a可能会是⼀个表达式,它只需计算评估⼀次,⽽a = a + 3中,a要计算两次。
2. 对于可变对象,可以直接在原处修改得到修改后的值,⽽普通的⼀元赋值表达式必须在内存中新创建⼀个修改后的数据对象,并赋值
给变量
第⼀点⽆需解释。关于第⼆点,看下⾯的例⼦:
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):快
对于上⾯(1)和(4)的⼀元赋值表达式,先取得L,然后创建⼀个新的列表对象,将L拷贝到新列表对象中,并将4或5,6放进新列表对象,最后赋值给L。这个过程中涉及到了⼏个步骤:新分配内存、内存中列表拷贝、放⼊新数据。
⽽(2)(3)是等价的,(5)(6)也是等价的,它们都是直接在内存中的原始列表处修改,不会有拷贝操作,新建的数据对象仅仅只是⼀个元素。
按照理论上来说,确实⼆元赋值⽅式要效率⾼⼀些,但要注意的是,列表中保存的只是各元素的引⽤,
所以拷贝列表也仅仅只是拷贝⼀点引⽤,这是微乎其微的开销。所以⼀元赋值和⼆元赋值的差距在这⼀点的性能上基本没差距,主要的差距还在于⼀元、⼆元赋值⽅式可能存在的表达式不同评估次数。
总的来说,使⽤⼆元赋值表达式通常可以作为可变对象赋值的⼀种优化⼿段。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。