【python】可变、不可变数据类型

文章目录

  • python可变、不可变数据类型
  • 一、什么是可变和不可变的数据类型?
  • 二、不可变类型
    • 1.数字
    • 2.字符
    • 3.元组
  • 三、可变类型
    • 4.列表
      • 需要注意的点
    • 5.集合
    • 5.字典
    • 6.补充 -深拷贝和浅拷贝
  • 总结


python可变、不可变数据类型

用于记录python数据类型

python我个人常用的数据就是数字、字符串、元组、列表、集合、字典,分为可变类型不可变类型


一、什么是可变和不可变的数据类型?

可变就是说在相同内存地址的内容可以发生改变,反之,不可变类型就是相同地址的内容不能被修改。

二、不可变类型

1.数字

#数字
a=1.0
print(id(a), type(a))
a=2.0
print(id(a), type(a))

输出:

2633529434384 <class 'float'>
2633566302832 <class 'float'>

本以为数字相同变量,重新赋值后还在相同地方,其实他已经修改了地址了。。不过不影响使用就是了。

2.字符

#字符
a="a"
print(id(a), type(a))
a="b"
print(id(a), type(a))

输出:

2633529434384 <class 'float'>
2633566302832 <class 'float'>

字符也是另外的地址了

3.元组

#元组
#元组可以当作是没有类型的数组,不可被改变
a=(1,2)
print(id(a), type(a))
a=(3,4)
print(id(a), type(a))
a[0]=0
#报错,不能被重新赋值

输出:

2633566244032 <class 'tuple'>
2633566657280 <class 'tuple'>
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [7], line 7
      5 a=(3,4)
      6 print(id(a), type(a))
----> 7 a[0]=0

TypeError: 'tuple' object does not support item assignment

字符也是另外的地址了

三、可变类型

4.列表

##列表
#元组用小括号
a=(1,2)
#列表用中括号
b=[3,2]
print(b)
#重新赋值
#a[0]=3  #出错
b[0]=1  #可运行
print(b)

输出:

[3, 2]
[1, 2]

但是元组和列表使用numpy转成数据就相同了。我们在正常使用中通常是用到numpy的,所以是没问题的。

#转成numpy就一样了
#元组转numpy数组 
import numpy as np

c=np.array(a,dtype=np.uint8)
d=np.array(b,dtype=np.uint8)
print("a:",a)
print("b:",b)
print("c:",c)
print("d:",d)
print(c==d)

输出:

a: (1, 2)
b: [1, 2]
c: [1 2]
d: [1 2]
[ True  True]

需要注意的点

由于列表是可变类型,因此如果使用浅拷贝会改变原始值、目标值。

b=[3,2] #原始值
print(b)
c=b #浅拷贝 C为目标值

c[0]=1 
print(b) #目标值改变导致原始值改变
print("//")
print(c)
b[0]=4 
print(c) #原始值改变导致目标值改变

输出:

[3, 2]
[1, 2]
//
[1, 2]
[4, 2]

若不想改变可用深拷贝

##深拷贝互不影响
import copy
b=[3,2] #原始值
print(b)
c=copy.deepcopy(b) #深拷贝 C为目标值

c[0]=1 
print(b) #目标值改变,不影响原始值
print("//")
print(c)
b[0]=4 
print(c) #原始值改变,不影响目标值

输出:

[3, 2]
[3, 2]
//
[1, 2]
[1, 2]

5.集合

# 集合
set1 = {1, 2, 3, '123'}
print("集合:", set1, "内存地址:", id(set1), "\t", "数据类型:", type(set1), "\t")

# 给set1删除一个元素
set1.remove(2)
print("集合:", set1, "内存地址:", id(set1), "\t", "数据类型:", type(set1), "\t")

输出:

集合: {'123', 1, 2, 3} 内存地址: 2635583510784 	 数据类型: <class 'set'> 	
集合: {'123', 1, 3} 内存地址: 2635583510784 	 数据类型: <class 'set'> 

5.字典

#字典
#采用键值对(key-value)的形式存储数据
dict1 = {'name': 'abc', 'age': 18}
print("字典:", dict1, "内存地址:", id(dict1), "数据类型:", type(dict1))

#重新赋值
dict1['sex'] = 'man'
print("字典:", dict1, "内存地址:", id(dict1), "数据类型:", type(dict1))

注意事项与列表相同

输出:

字典: {'name': 'abc', 'age': 18} 内存地址: 2635718986560 数据类型: <class 'dict'>
字典: {'name': 'abc', 'age': 18, 'sex': 'man'} 内存地址: 2635718986560 数据类型: <class 'dict'>

注意事项与列表相同

6.补充 -深拷贝和浅拷贝

深拷贝:对原对象的地址的拷贝,新拷贝了一份与原对象不同的地址的对象,修改对象中的任何值,都不会改变深拷贝的对象的值。

浅拷贝:对原对象的值的拷贝,地址仍是一个指针指向原对象的地址,浅拷贝或者原对象的值发生变化,那原对象和浅拷贝对象的值都会随着被改变。

浅拷贝(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用

深拷贝(深度克隆):不仅复制对象的基本类,同时也复制原对象的对象,完全是新对象产生的

copy.copy #浅拷贝

copy.deepcopy #深拷贝

总结

个人学习中想要记录的一些东西,
不可变数据类型中的数字和字符,对日常使用无影响,元组只要记住不可变就行,因为不可被串改,因此可作为记录使用。若想使用能改变的就用列表或转成numpy数组。
可变数据类型记住浅拷贝的时候,原始值和目标值改变一个,另外一个也会发生改变。

你可能感兴趣的:(python,python,numpy,开发语言)