Python学习笔记--可变数据类型与不可变数据类型

Python的标准数据类型主要包括:

  1. Number(数字):包括 int,float,bool,complex(复数)
  2. String(字符串)
  3. List(列表)
  4. Tuple(元组)
  5. Set(集合)
  6. Dictionary(字典)

其中 Number,String,Tuple,是不可变数据类型,List,Set,Dictionary属于可变数据类型。

不可变数据类型:

当该类型对应的变量的值改变时,变量的内存地址也改变了
补充:id(object) :Python内置函数,用于获取类型的内存地址 菜鸟教程地址
示例:

>>> a = 10
>>> b = 10
>>> id(a)
140709500838832
>>> id(b)
140709500838832
>>> a = 11
>>> id(a)
140709500838864

可以看出同一个值的数字类型的变量指向同一个内存地址,当变量a的值改变时,它的内存地址也改变了。而且一个值为较小的数字类型的变量(例:a = 10)被分配到内存中,那么其他等于这个值的变量都会指向同一个内存地址。但是这一特性只在 -5~256 (int)之间存在。float不存在这一特性。对于string,同一个字符串指向同一个地址。这称为不可变对象的复用
示例:

>>> a = -5
>>> b = -5
>>> id(a)
140709456601552
>>> id(b)
140709456601552
>>> a = -6
>>> b = -6
>>> id(a)
2386350131088
>>> id(b)
2386380657296
>>> a = 'qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq'
>>> b = 'qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq'
>>> id(b)
2386380681584
>>> id(a)
2386380681584

此外不可变数据类型还有一个特性,指向同一个内存地址的不同变量不会相互影响
示例:

>>> a = 10
>>> b = a
>>> a += 1
>>> print(b)
10
>>> print(a)
11

是因为变量的值改变时会生成一个副本,变化会作用在副本上。所以在将不可变数据类型作为参数时要注意保证修改的有效性。
示例:

s = 'abc'
def change(s):
    s = "aaa"
    print(s, 'inter string')
    return s
change(s)
print(s, 'out string')
s = change(s)
print(s, 'out string')

运行结果:

aaa inter string
abc out string
aaa inter string
aaa out string

可变数据类型:

当此类型的变量的值发生变化时,变量的内存地址不会发生改变
示例:

>>> a = []
>>> b = a
>>> id(a)
2386350334664
>>> id(b)
2386350334664
>>> a.append(1)
>>> id(a)
2386350334664
>>> print(b)
[1]
>>> b.append(2)
>>> id(b)
2386350334664
>>> print(a)
[1, 2]

同时可以看出指向同一个内存地址的可变数据类型会相互影响

参数传递

python中的参数传递是传引用,也就是传参数的内存地址,所以对于不可变数据类型不能直接改变变量的值,如 Number,String。它们会生成一个副本供函数使用,副本的变化,不会影响函数外的原始值。对于list,dictionary等可变数据类型可以直接改变变量的值
示例:

s = 'abc'
def change(s):
    s = "aaa"
    print(s, 'inter string')
    return s
l = []
def add(list1):
    list1.append(1)

if __name__ == "__main__":
    add(l)      #直接影响原始值
    for i in range(len(l)):
        print(l[i])
        
    change(s)   #没有影响到原始值
    print(s, 'out string')
    s = change(s)    #对实参重新赋值,保证修改有效
    print(s, 'out string')

运行结果:

1
aaa inter string
abc out string
aaa inter string
aaa out string

对于元组来说,相对复杂。元组本身属于不可变数据类型变量,但是元组内可以包含列表等可变数据类型变量。如果参数是嵌套的,修改限制由外向内,直接相连的两层,外层限制内层,不直接相连没有影响。以元组嵌套 列表为例,元组中的元素是不能修改的,但是元组中列表的元素可以直接修改。
示例:

arry = []
t = (1, 'b', arry)
def translate(tuple1):
    tuple1[2].append(1)
if __name__ == "__main__":
    print(t, 'start')
    translate(t)
    print(t, 'end')

运行结果:

(1, 'b', []) start
(1, 'b', [1]) end

可以看出元组中的列表的元素是可以被修改的。我们在来看一个不能修改的例子,当列表中的元素为元组时的情况。
示例:

a = []
a.append(('a', 1))
a.append(('b', 2))
print(a[0][1])
a[0][1] += 1
print(a[0][1])

运行结果:

1
Traceback (most recent call last):
  File "c:/Users/hasee/Desktop/111-1.py", line 25, in <module>
    a[0][1] += 1
TypeError: 'tuple' object does not support item assignment

可以看出,当列表的元素为元组时,是不能直接修改其中元组的元素的。应该先把要修改的元组从列表中删除,再把新元组加入到列表,不过这样会引起下标的改变,要注意。
示例:

a = []
a.append(('a', 1))
a.append(('b', 2))
print('before', a[0][1])
a.pop(0)
a.append(('a', 3))
print('after', a[0][1])
print('-----------')
print(a)

运行结果:

before 1
after 2
-----------
[('b', 2), ('a', 3)]

以上是我的学习经验,如果有错误的地方,欢迎指出来,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值