1 copy()
copy()方法可以对字典进行潜复制。
语法:
字典1 = 字典2.copy()
Q:为什么d1 = d2不是复制?
A:这种做法是将 d2 的值赋予 d1,是赋值,不是复制。
用id()
分别返回 d1 和 d2 的id可以看到 d1 和 d2 的id值是相同的。说明 d1 和 d2 指向的是同一个对象。如果修改 d1 的对象,d2 的对象也会变化。
复制则不会出现以上现象。
例:复制字典d1 = {'a':1, 'b':2, 'c':3}
代码:
d1 = {'a':1, 'b':2, 'c':3}
d2 = d1.copy()
print(d1,id(d1))
print(d2,id(d2))
执行结果:
根据以上执行结果可知,d1与d2的id值不同,说明是两个不同的对象。
1.1 潜复制概述
代码:
d1 = [1, 2, 3, [4, 5, 6]]
d2 = d1.copy()
print('改前:')
print(d1, id(d1))
print(d2, id(d2))
d1[0] = 0 # 第二次执行时,这行改为:d1[3][0] = 0
print('改后:')
print(d1, id(d1))
print(d2, id(d2))
执行结果 1:
根据执行结果1可知:修改了 d1 列表中的元素不会对 d2 列表内的元素产生影响。但是,如果我们修改 d1 列表中的子列表,结果会不同。
执行结果 2:
根据执行结果2可知:虽然 d1 和 d2 不是同一个对象,但当 d1 中的子序列被改变时,d2 的也会同时改变。然后,我们再通过id判断 d1 与 d2 的子序列之间的关系,得出以下结果:
执行结果 3:
根据执行结果3可知:d1 和 d2 的子序列是同一个对象。所以,当其中一个子序列发生变化时,另一个也会发生同样的变化。
总结:潜复制只会复制序列本身(第一层),如果序列中有子序列(第二层),则子序列不会复制,而是赋值。
* 1.2 深复制概述
深复制与潜复制不同,深复制不仅可以复制序列本身,它还可以复制序列中的子序列。
语法:
import copy() # 导入copy()模块
字典1 = copy.deepcopy(字典2)
2 遍历字典
有三种常用的遍历字典的方法
方法 | 说明 |
---|---|
keys() | 返回字典所有的key |
values() | 返回一个序列,序列中保存有字典的值 |
items() | 返回字典所有的项,然后保存到一个序列中,序列中包含有双值子序列,双值为字典的 key 和 value |
- key()
语法:
字典1.keys() # class'dict.keys'
- values()
语法:
字典.values()
- items()
语法:
字典.items()
3 集合(set)
集合与列表很相似。不同点在于,集合中只能存储不可变对象;集合中元素是无序的(不按照元素插入的顺序);集合中不能出现重复元素。
3.1 创建集合
语法:
集合 = {元素1,元素2,...}
# 集合可以为空,但通过{}创建的不是空集合,而是空字典。
#使用set()可以创建空集合
如果给集合插入对象时出现重复对象,则会重复的对象会合并成一个对象。
如果集合中有可变对象,则会报错:
TypeError: unhashable type: ‘list’
3.1.1 set()
通过 set() 函数可以将序列和字典转换为集合。
语法:
变量 = set(序列 或 字典)
如果用set()将字典转换为集合时,只会包含字典的key
注:无法通过取索引的方式获取集合的值,会报错:
TypeError: ‘set’ object is not subscriptable
3.2 集合的使用
3.2.1 in 和 not in
in:用于判断对象是否在集合中。存在则返回True,否则返回False
not in :用于判断对象是否不在集合中。存在则返回False,否则返回True
语法:
对象 in 集合
对象 not in 集合
3.2.2 add()
add()可以向集合中添加元素。
语法:
集合.add(元素)
3.2.3 update()
update()也可以向集合添加元素,只是是将一个集合的元素添加到另一个集合中。
语法:
集合1.update(集合2)
# 将集合2添加到集合1中
3.2.4 pop()
随机删除集合中的一个元素。同时将删除的元素作为返回值返回。
语法:
集合.pop()
3.2.5 remove()
删除集合中指定的元素。
语法:
集合.remove(元素)
3.2.6 clear()
清空集合。
语法:
集合.clear()
4 集合的运算
我们以s1 = {1, 2, 3, 4, 5}
和s2 = {3, 4, 5, 6, 7}
为例
4.1 & (交集运算)
代码:
s1 = {1, 2, 3, 4, 5}
s2 = {3, 4, 5, 6, 7}
print(s1)
print(s2)
r = s1 & s2
print('计算结果:',r)
执行结果:
4.2 | (并集运算)
代码:
s1 = {1, 2, 3, 4, 5}
s2 = {3, 4, 5, 6, 7}
print(s1)
print(s2)
r = s1 | s2
print('计算结果:',r)
执行结果:
4.3 - (差集运算)
代码:
s1 = {1, 2, 3, 4, 5}
s2 = {3, 4, 5, 6, 7}
print(s1)
print(s2)
r = s1 | s2
print('计算结果:',r)
执行结果:
注:这里的 -
,指的不是减法运算,在差集运算中,s1 与 s2的差集,和 s2 与 s1 的差集是不同的 。
4.4 ^ (亦或集)
亦或集指的就是集合1与集合2不相交的部分。
代码:
s1 = {1, 2, 3, 4, 5}
s2 = {3, 4, 5, 6, 7}
print(s1)
print(s2)
r = s1 ^ s2
print('计算结果:',r)
执行结果:
5 函数
概述:函数也是一种对象(function)函数可以用来保存代码,在需要的时候可以多次调用。如:print()、input()等
语法:
def 函数名(参数1,参数2,...):
代码块
代码:
def myFunction():
print('hello world')
print(myFunction)
执行结果1:
执行结果没有出现‘hello world’,而是:<function myFunction at 0x000001FEAE5AB1F8>。这个是函数的内存地址值,因为我们的调用方式不对,这种是函数对象,返回的是函数的内存地址。调用函数的标准格式是:
函数对象()
执行结果2:
5.1 函数的参数
在定义函数的时候可以定义多个形参(形式参数)。通过函数的参数,可以让实现实现多种功能。
形参是在函数内部声明的变量。如果函数定义了形参,就必须调用同等数量的实参。
Q:如何判断实参和形参?
A:看赋值的关系可以判断。通常情况下,在函数中,形参是被赋予值的参数,本身并没有值。而实参是赋予值的参数,本身通常是有值的。
- 例1:用函数求任意两个数的和
代码:
def mySum(x, y):
print(x, '+', y, "=", x + y)
mySum(1, 2) # 将1,2分别赋予x,y
# 这里1,2为实参,x,y为形参
执行结果:
定义形参的时候,可以为形参指定默认值。
语法:
def 函数名(参数1 = default_1, 参数2 = default_2,...)
默认值只有在用户没有传递对应参数的时候才会生效。
5.2 函数的传递方式
传递方式通常有以下几种:
我们用以下代码块为例子:
def fn(a,b,c):
print('a = ', a)
print('b = ', b)
print('c = ', c)
方式 | 说明 |
---|---|
位置传参 | 将对应位置上的实参赋值给对应位置上的形参,如:fn(1,2,3) |
关键字传参 | 可以不按形参定义的顺序,直接根据参数名取传递。如:fn(b = 3, a = 2, c = 4) |
位置参数和关键字参数可以混合在一起用,但是关键字参数不能在位置参数前面。