深浅copy
python中有很多可变的数据,如列表,字典。
因为具有可变性,而python中的赋值只是对对象的引用,并不是复制对象。
所以,处理可变数据时,由于其可变性,就会很麻烦,稍不小心就会改变对象。
于是就出现了copy(复制),即创建副本。
copy分为深copy和浅copy。
浅copy:
a = [1, 2, 3, [1, 2, 3], 4] # 原对象
b = a.copy() # 副本
a.append(5) # 原对象发生了变化
a[3].append(5) #原对象中的嵌套对象发生了变化
print(a) # 发生了两次变化
print(b) # 发生了一次变化,嵌套对象变了 b的目的是copy原对象
# 说明浅拷贝的话只能复制第一层,嵌套层还是可变的
>>>
[1, 2, 3, [1, 2, 3, 5], 4, 5]
[1, 2, 3, [1, 2, 3, 5], 4]
[1, 2, 3, [1, 2, 3, 5], 4, 5]
[1, 2, 3, [1, 2, 3, 5], 4]
深copy:则是完全copy。
调用方式:
import copy
b = copy.deepcopy(a)
a.append(2)
a[3].append(5)
print(a)
print(b)
>>>
[1, 2, 3, [1, 2, 3, 5], 4, 2]
[1, 2, 3, [1, 2, 3], 4] # 实现了完全copy对象
深copy实现了创建可变数据类型的复制对象功能。
深浅copy适用于可变的数据类型(列表,字典),不可变的数据类型没必要copy,因为根本就不会变呀,再怎么赋值都是创建了一个新对象。
补充知识点
L = [('a', 'c'), (1, 'abc'), (4, 'efg')]
for x, y in L:
print(x, y)
>>>a c
1 abc
4 efg
L必须可迭代,且以(x,y)形式表示,可以是列表也 可以是元组,但必须是(x,y)的形式。
用一行代码实现a, b互换
a = 1
b = 2
a, b = b, a
print(a, b )
>>>2 1
enumerate()函数
枚举,适用对象是可迭代对象(可遍历),
返回值是(下标(可设置),元素)的元组序列。
——>enumerate(iterable,start=0)
常用在for循环中
L = [('a', 'c'), (1, 'abc'), (4, 'efg')]
print(list(enumerate(L)))
for x, y in enumerate(L, 1):
print(x, y)
print(enumerate(L))
>>>
[(0, ('a', 'c')), (1, (1, 'abc')), (2, (4, 'efg'))]
1 ('a', 'c')
2 (1, 'abc')
3 (4, 'efg')
<enumerate object at 0x0000000001F8D678>
id():查询数据的内存地址
s = 'abc'
n = 123
L = [1, 3, 4]
print(s, type(s), id(s))
print(n, type(n), id(n))
print(L, type(L), id(L))
>>>
abc <class 'str'> 32468864 # 地址是变动的
123 <class 'int'> 1423208480
[1, 3, 4] <class 'list'> 33043528
== 和 is
== 比较运算符,比较的是值。
is 比较是内存地址。
1,列表,元组,字典,集合。虽赋值是同一对象,但是**
内存地址不同。
L = [('a', 'c'), (1, 'abc'), (4, 'efg')]
l = [('a', 'c'), (1, 'abc'), (4, 'efg')]
print(L is l)
tu = ('a', 'b', 'c')
tu1 = ('a', 'b', 'c')
print(tu is tu1)
>>>
False
False
2,int 和 str 有点特殊
都有一个小数据池
int -5—256内的创建相同的数,指向同一个内存地址
字符串的话,长度不能超过20,有空格和特殊字符也不行。
具体参见d7编码笔记截图