1 潜复制
1.1 copy() – 对字典进行潜复制
d = {
'a': 1,
'b': 2,
'c': 3
}
d2 = d
d['a'] = 10
print('d =', d, 'id(d) =', id(d)) # d = {'a': 10, 'b': 2, 'c': 3} id(d) = 1712916422160
print('d2 =', d2, 'id(d2) =', id(d2)) # d2 = {'a': 10, 'b': 2, 'c': 3} id(d2) = 1712916422160
d = {
'a': 1,
'b': 2,
'c': 3
}
d2 = d.copy()
d['a'] = 10
print('d =', d, 'id(d) =', id(d)) # d = {'a': 10, 'b': 2, 'c': 3} id(d) = 2029305093648
print('d2 =', d2, 'id(d2) =', id(d2)) # d2 = {'a': 1, 'b': 2, 'c': 3} id(d2) = 2029305093720
结论:案例 1 中 d 和 d2 的 id 相同,指向同一个对象,所以案例 1 的操作不算复制,案例 2 中改变 d 中的元素,d2 中的元素不受影响,所以案例 2 是潜复制
d = {
'a': {
'name': '葫芦娃',
'age': 10
},
'b': 2,
'c': 3
}
d2 = d.copy()
d2['a']['name'] = '黑猫警长'
print('d =', d, 'id(d) =', id(d))
# d = {'a': {'name': '黑猫警长', 'age': 10}, 'b': 2, 'c': 3} id(d) = 1701251604056
print('d2 =', d2, 'id(d2) =', id(d2))
# d2 = {'a': {'name': '黑猫警长', 'age': 10}, 'b': 2, 'c': 3} id(d2) = 1701251633224
结论:潜复制只会复制字典本身,如果字典中还有字典是不会复制的
1.2 列表的潜复制
d = [1, 2, 3, [4, 5, 6]]
d2 = d.copy()
d[0] = 10
d[3][2] = 7
print('d =', d, 'id(d) =', id(d)) # d = [10, 2, 3, [4, 5, 7]] id(d) = 2367958395080
print('d2 =', d2, 'id(d2) =', id(d2)) # d2 = [1, 2, 3, [4, 5, 7]] id(d2) = 2367958394760
注:列表的潜复制性质、用法和字典的相同
*1.3 深复制(拓展内容)
import copy # 导入copy模块
d = {
'a': {
'name': '葫芦娃',
'age': 10
},
'b': 2,
'c': 3
}
d2 = copy.deepcopy(d)
d2['a']['name'] = '黑猫警长'
print('d =', d, 'id(d) =', id(d))
# d = {'a': {'name': '葫芦娃', 'age': 10}, 'b': 2, 'c': 3} id(d) = 1944509767256
print('d2 =', d2, 'id(d2) =', id(d2))
# d2 = {'a': {'name': '黑猫警长', 'age': 10}, 'b': 2, 'c': 3} id(d2) = 1944539778864
2 遍历字典的方法
- keys() - 该方法返回字典所有的 key
- values() - 该方法返回一个序列,序列中保存有字典的值
- items() - 该方法会返回字典中所有的项,它返回一个序列,序列中包含有双值子序列,双值分别是字典中的 key 和 value
2.1 方法 keys()
d = {
'name': '葫芦娃',
'age': 10,
'sex': '男'
}
# 获取key()方法的输出结果及其类型
print(d.keys(), type(d.keys())) # dict_keys(['name', 'age', 'sex']) <class 'dict_keys'>
# 遍历方法如下:
for k in d.keys():
print(k)
'''
结果:
name
age
sex
'''
2.2 方法 value()
d = {
'name': '葫芦娃',
'age': 10,
'sex': '男'
}
print(d.values(), type(d.values())) # dict_values(['葫芦娃', 10, '男']) <class 'dict_values'>
for v in d.values():
print(v)
'''
运行结果:
葫芦娃
10
男
'''
2.3 方法 items()
d = {
'name': '葫芦娃',
'age': 10,
'sex': '男'
}
print(d.items(), type(d.items())) # dict_items([('name', '葫芦娃'), ('age', 10), ('sex', '男')]) <class 'dict_items'>
for k, v in d.items():
print(k, v)
'''
结果:
name 葫芦娃
age 10
sex 男
'''
3 集合
3.1 基础知识
- 集合(set) – 和列表相似
- 集合与列表的不同点
- 集合中只能存储不可变对象
- 集合中存储的对象是无序的 (不是按照元素的插入顺序保存的)
- 集合中不能出现重复的元素
3.2 创建集合
- 使用 {} 创建集合
s = {10, 5, 3, 4, 3, 4, 3, 4}
print(s, type(s)) # {10, 3, 4, 5} <class 'set'>
错误案例:
s = {[1, 2, 3], [4, 5, 6]}
print(s)
# TypeError: unhashable type: 'list'
原因:集合中只能存放不可变对象,列表是可变对象
3.3 set() 函数
3.3.1 创建空的集合
s = set()
print(s, type(s)) # set() <class 'set'>
3.3.2 将序列和字典转换为集合
- 序列:
s = set([1, 2, 3, 4, 5, 1, 1, 1, 1])
print(s, type(s)) # {1, 2, 3, 4, 5} <class 'set'>
- 字典:
s0 = {
'a': 1,
'b': 2,
'c': 3
}
s = set(s0)
print(s, type(s)) # {'a', 'b', 'c'} <class 'set'>
注:使用 set() 函数将字典转换为集合时,结果只包含字典的键
3.3.3 错误案例:
s = {'a', 'b', 1, 2, 3}
print(s[0])
# TypeError: 'set' object does not support indexing
原因:集合是无序的,不能通过下标索引值找元素
修正方法: 将集合转换为列表之后查找
- 转换方法:
s = {'a', 'b', 1, 2, 3}
print(list(s)[0]) # 由于集合无序,每次打印的结果都不同
3.4 集合的使用
3.4.1 in 和 not in
- 检查集合中的元素(返回 True 或 False)
- in:元素在集合中返回 True,不在则返回 False
- not in :元素在集合中返回 False,不在则返回 True
s = {'a', 'b', 1, 2, 3}
print('a' in s) # True
print('a' not in s) # False
3.4.2 add()
- 向集合中添加元素
s = {'a', 'b', 1, 2, 3}
s.add(10)
s.add(30)
print(s) # {1, 2, 3, 'a', 10, 'b', 30}
3.4.3 update()
- 将一个集合中的元素添加到另一个集合中
s = {'a', 'b', 1, 2, 3}
s2 = set('hello')
s.update(s2) # 将 s2 添加到 s 中
print(s) # {1, 2, 3, 'e', 'l', 'b', 'h', 'o', 'a'}(集合具有无序性,每次运行结果中的元素相同,顺序随机)
3.4.4 pop()
- 随机删除集合中的一个元素
s = {'a', 'b', 1, 2, 3}
result = s.pop()
print(result) # 1 - 返回被删除的那个元素
print(s) # {2, 3, 'a', 'b'} (每次返回结果时的顺序都不相同)
3.4.5 remove()
- 删除集合中指定的元素
s = {'a', 'b', 1, 2, 3}
s.remove(2)
s.remove('b')
print(s) # {1, 3, 'a'}
3.4.6 clear()
- 清空集合中的元素
s = {'a', 'b', 1, 2, 3}
s.clear()
print(s) # set()
3.5 集合的运算
3.5.1 &
- 交集运算
s = {1, 2, 3, 4, 5}
s2 = {3, 4, 5, 6, 7}
r = s & s2
print(r) # {3, 4, 5}
3.5.2 |
- 并集运算
s = {1, 2, 3, 4, 5}
s2 = {3, 4, 5, 6, 7}
r = s | s2
print(r) # {1, 2, 3, 4, 5, 6, 7}
3.5.3 -
- 差集运算
s = {1, 2, 3, 4, 5}
s2 = {3, 4, 5, 6, 7}
r = s - s2
r2 = s2 - s
print(r) # {1, 2}
print(r2) # {6, 7}
3.5.4 ^
- 异或集运算(不相交的部分运算)
s = {1, 2, 3, 4, 5}
s2 = {3, 4, 5, 6, 7}
r = s ^ s2
print(r) # {1, 2, 6, 7}
3.5.5 <=、< 、>=、>
'''
<= 检查一个集合是否为另一个集合的子集
< 检查一个集合是否为另一个集合的真子集
>= 检查一个集合是否为另一个集合的超集
> 检查一个集合是否为另一个集合的真超集
'''
a = {1, 2, 3}
b = {1, 2, 3, 4, 5, 6}
r = a < b
print(r) # True
4 函数快速入门
- 函数是一个对象 function,可以用来保存一些可执行的代码,并且可以在需要的时候,多次对这些代码进行调用
- 语法
- def 函数名(形参 1, 形参 2, …):
- 代码块
- 函数对象() - 调用函数
- def 函数名(形参 1, 形参 2, …):
def fn():
print('这是我的第一个函数!')
fn() # 调用函数操作 输出结果为:这是我的第一个函数!
print(fn) # <function fn at 0x000001888BD81E18> 注:0x000001888BD81E18 为函数在电脑内存中的位置
注:fn 是函数对象,fn()是调用函数
例如 print 是函数对象,print()是调用函数
5 函数的参数 – 形参和实参
- 形参又叫形式参数,定义形参就是相当于在函数内部声明变量,不是赋值
- 实参(实际参数):如果函数定义时只定义了形参,那么在调用时也必须传递实参,实参将会赋值给对应的形参,形参个数必须等于实参
- 在定义函数的时候可以在函数名后面的括号中定义数量不等的形参,定义多个形参时要用逗号隔开
案例:定义一个函数用来求任意两个数的和
常见错误写法:
def fn2(a, b):
print('a =', a)
print('b =', b)
fn2()
# TypeError: fn2() missing 2 required positional arguments: 'a' and 'b'
原因:只有形式参数,缺少实际参数
正确写法 1:
def fn2(a, b): # a 和 b 是函数的形参
print('a =', a)
print('b =', b)
fn2(1, 2) # 结果:3 注:此处的 1 和 2 为实际参数,对应上面的形参 a 和 b
正确写法 2:
def fn2(a, b):
print(a, '+', b, '=', a+b)
fn2(1, 2) # 3
6 函数的传递方式
- 定义形参的时候可以为形参指定默认值
- 指定了默认值之后,如果用户传递了默认参数则默认值没有任何作用,如果用户未传递参数,则默认值生效
- 传递方式:
- 位置传参:将对应位置上的实参赋值给对应位置上的形参
- 关键字传参:可以不按照形参定义的顺序传递,可以直接根据参数名传递
def fn(a, b, c=20):
print('a =', a, end=' ')
print('b =', b, end=' ')
print('c =', c, end=' ')
fn(1, 2, 3) # a = 1 b = 2 c = 3
fn(1, 2) # a = 1 b = 2 c = 20
def fn(b=5, c=1, a=20):
print('a =', a)
print('b =', b)
print('c =', c)
fn(6, 5, 3) # a = 3 b = 6 c = 5