0916 数据类型与深浅拷贝
0916笔记
1.元组及内置方法
元组就是另一种有序的列表,只可取 不可更改的列表,元组创建时就被写死了。
1.元组的定义
tuple一旦初始化就不能修改,即没有append(),insert()这样的方法.
其他获取元素的方法和list列表是一样的,但不能赋值另外的元素
mat=('letme','mlxg','ming')
mat.append('xiaohu')
# 报错 AttributeError: 'tuple' object has no attribute 'append' 'tuple'对象没有属性'append'
优点: 因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。
缺点: 当你定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来
2.定义方式
()内用逗号隔开多个元素(可以为任意数据类型)
tup = tuple((1, 2, 3))
如果tuple只有一个元素就必须加逗号,不能 t=(1)
因为这个括号既可以表示tuple 又可以表示数学公式的小括号
tupl=(1,)
如果要定义一个空的tuple,可以写成
t=()
3.使用方法
1.索引取值
print(tup[0])
2.索引切片
print (tup[0:3])
3.for循环
for i in tup:
print(i)
4.成员运算
print (0 in tup)
5.len 长度
print (len (tup))
6.index 获取元素索引
print (tup.index(1))
7.count 计数
print (tup.count(2))
4.有序or无序
tuple就是另一种有序的列表。
5.可变or不可变
不能变化 定义元组--》占用内存小 --》 写死了
tuple的指向
# 定义一个元组中有列表的"可变"tuple
t = ('a', 'b', ['A', 'B'])
print(t)
# 输出('a', 'b', ['A', 'B'])
t[2][0] = 'X'
t[2][1] = 'Y'
print(t)
# 输出的是('a', 'b', ['X', 'Y'])
表面上,tuple的元素变了,但其实变得不是tuple的元素,而是list 的元素
tuple一开始指向的list并没有改变成别的list。
所以tuple所谓的‘不变’是说,tuple的每个元素,指向永远不变。即指向‘a’,就不能改成指向b,指向一个list,就不能指向其他对象,但指向的这个list本身是可变的。
2.字典
字符串、列表、字典 是最为常用的
列表替代元组,redis数据库替代集合
1.作用
存储多个值,dict为字典
2.定义方式
{}内用逗号隔开多个键值对。
键:key 必须具有描述意义,不能为不可变类型,
值:value 任意数据类型
3.使用方法
1.按key取值/按key修改值
d={'uzi':2800,'clearlove':4396,'xiaohu':90000}
print(d['uzi'])
# 输出 2800
2.按key增加值 没有就添加,有就修改
d={'uzi':2800,'clearlove':4396,'xiaohu':90000}
d['ming']=1
print(d)
''' 输出
{'uzi': 2800, 'clearlove': 4396, 'xiaohu': 90000, 'ming': 1}
3.for 循环
for I in dic:
print(i)
4.成员运算
print('a' in dic)
5.len 长度
print(len (dic))
6.keys / values / items
获取所有的键、值、键值对
print(dic.keys()) # 看成列表
print(dic.values()) # 获取所有值
print(dic.items())
for i in dic.items():
print(i)
for kasdfsad, vsdfsdf in dic.items(): # 解压缩
print(kasdfsad, vsdfsdf)
pop删除值
.pop(key)
对应的value也会从dict中删除
d={'uzi':2800,'clearlove':4396,'xiaohu':90000}
d.pop('uzi')
print(d)
# 输出 {'clearlove': 4396, 'xiaohu': 90000}
dict内部存放的顺序和key放入的顺序是没有关系的。
需要掌握
1 get方法
如果取值打印时,key并不存在,会报错。但是可以用in 判断key是否存在
d={'uzi':2800,'clearlove':4396,'xiaohu':90000}
print('baolan' in d) # 输出 false
在用.get方法时如果不存在,则返回none,或者指定value
d={'uzi':2800,'clearlove':4396,'xiaohu':90000}
print(d.get('letme'))
# 输出None
print(d.get('letme',4000))
# 加上值,输出 4000
2.update :
更新,等同于list里的extend
dic1 = {'a': 1, 'c': 2}
dic2 = {'b': 1, 'd': 2}
dic1.update(dic2)
print(dic1)
# {'a': 1, 'c': 2, 'b': 1, 'd': 2}
3.formkeys
键值对统一赋值
# dic之fromkeys()
dic = dict.fromkeys(['name', 'age', 'sex'], None)
print(f"dic: {dic}")
# dic: {'name': None, 'age': None, 'sex': None}
4.setdefault
字典中有key 就不修改,没有则增加
dic = {'a': 1, 'b': 2}
print(f"dic.setdefault('a'): {dic.setdefault('a',3)}")
print(f"dic: {dic}")
print(f"dic.setdefault('c'): {dic.setdefault('c',3)}")
print(f"dic: {dic}")
4.有序or无序
无序(并没有索引)
5.可变or不可变
可变,但key必须是不可变的
因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key:
d={'uzi':2800,'clearlove':4396,'xiaohu':90000,[1,2,3]:123}
print(d)
# 报错 TypeError: unhashable type: 'list'
# key 不能当做列作 但是值可以使列表
3.集合
set和dict类似,也是一组key的集合,但是不存储value。由于key不能重复,所以,在set中,没有重复的key。
1.作用
1.可以进行交集/并集/补集/差集运算 2.去重 3.乱序 ==》基于散列表实现的
2.定义方式(set)
{}内以逗号隔开多个元素(不能可为变数据类型)
s={}
定义空字典。
s=set{}
定义空集合
3.使用方式
pythoners = {'jason', 'nick', 'tank', 'sean'}
linuxers = {'nick', 'egon', 'kevin'}
# 并集
print(pythoners | linuxers)
# {'sean', 'kevin', 'egon', 'jason', 'tank', 'nick'}
# 交集
print(pythoners & linuxers)
# {'nick'}
# 差集
print(pythoners - linuxers)
# {'sean', 'tank', 'jason'}
# 补集
print(pythoners ^ linuxers)
# {'kevin', 'egon', 'jason', 'sean', 'tank'}
# add(*******)
pythoners.add('oscar')
print(pythoners)
# {'jason', 'sean', 'oscar', 'tank', 'nick'}
#
# pythoners.remove('oscar1') # 没有报错
# print(pythoners)
# pythoners.discard('oscar1') # 没有不报错
# print(pythoners)
pythoners.pop() # 随机删除一个
print(pythoners)
# {'sean', 'oscar', 'tank', 'nick'}
set和dict的唯一区别仅在于没有存储对应的value,
但是,set的原理和dict一样
同样不可以放入可变对象,因为无法判断两个可变对象是否相等
也就无法保证set内部“不会有重复元素”。
4.有序or无序
无序
5.可变or不可变
可变
4.数据类型总结
() tuple 元组
[] list 列表
{:} dict 字典 (键值对)
set() set 集合 {}
# 存值个数
# 存一个值:整型/浮点型/字符串
# 存多个值:列表/元组/字典/集合
# 有序or无序
# 有序:字符串/列表/元组(序列类型)
# 无序:字典/集合
# 可变or不可变
# 可变:列表/字典/集合
# 不可变:整型/浮点型/字符串/元组xxxxxxxxxx14 1# 存值个数23# 存一个值:整型/浮点型/字符串4# 存多个值:列表/元组/字典/集合567# 有序or无序8# 有序:字符串/列表/元组(序列类型)9# 无序:字典/集合101112# 可变or不可变13# 可变:列表/字典/集合14# 不可变:整型/浮点型/字符串/元组# 存值个数# 存一个值:整型/浮点型/字符串# 存多个值:列表/元组/字典/集合# 有序or无序# 有序:字符串/列表/元组(序列类型)# 无序:字典/集合# 可变or不可变# 可变:列表/字典/集合# 不可变:整型/浮点型/字符串/元组python
5.深浅拷贝
用一定用不到,面试很大概率会问,这不是python独有的,而是一种语言独有的
Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果,其实这个是由于共享内存导致的结果
在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用
1.拷贝
copy
原则上就是把数据分离出来,复制其数据,并以后修改互不影响。
2.浅拷贝
copy.copy
数据半共享(复制其数据独立内存存放,但是只拷贝成功第一层),浅拷贝是对于一个对象的顶层拷贝,通俗的理解是:拷贝了引用,并没有拷贝内容
3.深拷贝
copy.deepcopy
数据完全不共享(复制其数据完完全全放独立的一个内存,完全拷贝,数据不共享)