Python的标准数据类型主要包括:
- Number(数字):包括 int,float,bool,complex(复数)
- String(字符串)
- List(列表)
- Tuple(元组)
- Set(集合)
- 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)]
以上是我的学习经验,如果有错误的地方,欢迎指出来,谢谢。