目录
这次我们会介绍一下字典和集合:
一、字典的基本概念
1、字典
字典在Python中用花括号,里面的每个元素由一对“键”和“值”两部分组成,可以根据“键”的快速查找
格式:a = {key1 :value1 , key2 :value2}
字典中的元素的“值”是可以赋值的,所以也是指针
所有的元素的键都是不相同的
在字典中,键必须是不可改变的数据类型(如:字符串,整数,小数,元组)
我们可以通过访问字典中的键,来输出其对应的值:
a = {"Sue":20 , 'Cat':0 , 12306:1 , (1,2,3):[1,2,3]}
print(a["Sue"])
输出:
注意!如果我们要输出字典a中不包含的键,程序就会输出异常!
我们可以直接通过键来修改其对应的数值:
a["Sue"] = 21
注意!虽然我们直接输出不存在的键,会导致程序异常,但是如果我们用修改的方法输入一个不存在的键值对,就相当于在字典中添加了这个键值对:
a = {"Sue":20 , 'Cat':0 , 12306:1 , (1,2,3):[1,2,3]}
a["zhangsan"] = 99
print(a)
(关于字典的输出:在Python的3.5版本及以前,字典的输出是无需的,也就是说你输出的顺序是12345,但输出的顺序可能是52341(不确定的),但是在3.6及以后的版本,输出的顺序和输入的顺序是相同的)
在Python中,我们可用del关键字来删除指定的键值对:
del a["zhangsan"]
我们可以用in关键字,来判断是否有元素键,在字典中
print("Sue" in a)
2、get()函数
基本格式:get(key,v)
运行顺序:如果键key存在,就返回键对应的值,如果不存在,就返回v
a = {"Sue":20 , 'Cat':0 , 12306:1 , (1,2,3):[1,2,3]}
b = a.get("Sue" , 0)
c = a.get("mimimi" , 0)
print(b)
print(c)
输出:
3、字典的键
字典的键不能一样,指的是字典的键的内容不能一样,如果出现重复的键,就会被新的覆盖,那么就会按照最后一个的键值对的值进行输出:
b = {'1':1 , '1':2 , '1':3 , '1':4}
print(b)
输出:
4、字典的构造
除了直接构造一个字典之外,我们还有其他的方式来生成一个字典:
我们可以用包含元组的列表,再结合dict()函数,把列表中的元组转化为一个字典(元组中需要包含两个数值,一个是键一个是值)
a = [("name" , "Sue") , ("age" , 19)]
b = dict(a)
print(b)
结果:
或者我们在dict()函数中,使用键 = 值 的形式,也可以直接构造出字典:
b = dict(name = "Sue" , age = 19)
print(b)
结果和上面的一样
二、字典的相关函数
函数 | 功能 |
clear() | 清空字典 |
keys() | 取字典的键的序列 |
items() | 取字典的元素的序列,可用于遍历字典 |
value() | 取字典的值的序列 |
pop(x) | 删除键为x的元素,如果不存在,就产生异常 |
copy() | 浅拷贝 |
注意!上述的“序列”不是指的列表,元组,集合等!
三、字典的深拷贝
和之前的列表一样,字典的拷贝也有深浅之分:
我们下面来看两个例子:
我们先对字典进行浅拷贝,会发现它只能对最外层进行嵌套,而内层的那个列表依旧是两个字典共同指向的:
a = {"Sue":20 , 'Cat':0 , 12306:1 , (1,2,3):[1,2,3]}
b = a.copy()
a[(1,2,3)].append(99999)
print(a)
print(b)
输出:
下面我们再用深拷贝:
import copy
a = {"Sue":20 , 'Cat':0 , 12306:1 , (1,2,3):[1,2,3]}
b = copy.deepcopy(a)
a[(1,2,3)].append(99999)
print(a)
print(b)
输出:
注意!我们这里是用append()来对列表进行增添元素的,并没有增加新的元素但是如果我们对字典的某一个键的值进行修改,就会在内存中生成新的元素,那是使用深浅拷贝都是无效的!
例子:
import copy
a = {"Sue":20 , 'Cat':0 , 12306:1 , (1,2,3):[1,2,3]}
b = copy.deepcopy(a)
a[(1,2,3)] = [1,2,3,99999]
print(a)
print(b)
#---------------------1------------------------
a = {"Sue":20 , 'Cat':0 , 12306:1 , (1,2,3):[1,2,3]}
b = a.copy()
a[(1,2,3)] = [1,2,3,99999]
print(a)
print(b)
#---------------------2------------------------
试着在电脑上运行这两个代码,你会发现无论是深拷贝,还是浅拷贝,都是同样的结果:
这就是因为我们‘a[(1,2,3)] = [1,2,3,99999]’这步操作,相当于是重新在内存中新建了一个值,让a指向这个新的数值,而b仍然指向原来的数值。因此,在这个键上,两个字典不会受到相互影响。
四、遍历字典
在Python中,我们可以用items来遍历字典,他会遍历字典中的每一个键和值:
a = {"Sue":20 , 'Cat':0 , 12306:1 , (1,2,3):[1,2,3]}
for i in a.items() :
print(i[0]) #代表字典中所有的键
print(i[1]) #代表字典中所有的值
输出:
有了这个我们就可以干非常多的事情,比如统计单词的出现频率:
zidian = {} #先建立一个空的字典,一会会把输入的数值放到字典里
while True :
try :
word = input("请输出需要统计的单词:") #获取单词的输入
if word in zidian :
zidian[word] = zidian[word] + 1 #如果单词已经存在在字典中,就+1
else :
zidian[word] = 1 #否则把数值初始化成1
except KeyboardInterrupt: #获取异常,当我们结束运行,循环就会停止
break
result = [] #一会会把字典里的键值对放到这个列表里面(因为列表是支持排序的)
for i in zidian.items():
result.append(i) #先把字典里的键值对一个个的放进列表里面
result.sort(key = lambda i:(-i[1] , i[0])) #根据出现的次数排序,出现次数多的,其相反数就小,就会被排在前面
print("\n") #换行,为了美观,其实不写也行
for j in zidian.items():
print(j[0] , j[1]) #输出
输出:
五、集合
1、集合的特点
Python中的集合,和数学中的集合的概念相同,所以它将会有一下的特点:
①集合中的元素类型可以不同
②集合中不会有重复的元素(即使你输出了重复的元素,输出是也会被合并成一个)
③可以增删元素
④整数、小数、复数、字符串、元组等都可以作为集合的元素,但是列表、集合、字典等数据就不行
⑤集合可以快速的判断某个东西是否在某一堆东西里面
2、构造集合
集合可以使用set()把列表,字符串,字典等数据转换为集合(字典转为集合的时候,只会把其中的“键”取下来当作字典的元素
因为字典没有顺序,所以我们不能通过下标去访问元素
3、集合常用的函数
函数 | 作用 |
add(x) | 添加元素x,如果x已经存在,则不添加 |
clear() | 清空集合 |
copy() | 返回自身的浅拷贝 |
remove(x) | 删除元素x,如果元素x不存在,就引发异常 |
update(x) | 将序列x的元素加到集合 |
4、集合的运算
运算 | 意义 |
x in a | x是否在集合a中 |
a | b | 求a和b的并集 |
a & b | 求a和b的交集 |
a - b | 求a和b的差,即存在在a中但不存在在b中的元素 |
a ^ b | 求a和b的对称差,即(a | b)-(a & b) |
a == b | a和b的元素是否一样 |
a != b | a和b的元素是否不一样 |
a <= b | a是不是b的子集(a有的元素,b都有) |
a < b | a是不是b的真子集(a有的元素,b都有,并且b中还有a中没有的元素 |
a >= b | b是不是a的子集 |
a > b | b是不是a的真子集 |
5、集合的应用
例子:输入一些单词,统计不重复的单词一共有多少个
words = set([])
while True:
try :
a = input("请输入单词:")
if not a in words :
words.add(a)
except KeyboardInterrupt :
break
print(len(words))
输出:
六、时间复杂度
1、了解时间复杂度
一个程序或算法的时间效率,也称时间复杂度,简称“复杂度”
时间复杂度常用大写字母O和小写字母n,比如O(n),O(n^2)等,O(x)表示解决问题的时间和x成正比
在无序数列中查找某个数,复杂度是O(n)
如果一个程序中时间复杂度是多个n的函数之和,则只关心随n增长最快的那个
例如O(n!+3^n)就可以看成O(n!)
2、不同的算法的时间复杂度
①O(1):集合,字典的增删元素,用关键字和下标访问数据
②O(n):列表,元组查找元素(in,index),列表插入元素(insert),删除元素(remove),计算出现的次数(count)
③O(nlog(n)):python自带的程序sort,sorted
④O(log(n)):在排好序的元组,列表上进行二分查找
3、in关键字的区别
在“a in b ”中,如果b是列表,字符串,元组,则时间复杂度是O(n),也就是说处理时间和元素b的个数是成正比的,但是若b是字典或集合,则时间复杂度是O(1),即时间基本是常数,和b无关,所以在判断元素是否存在于某个集合中时,应该优先使用字典或集合,而不是列表或元组。
以上就是Python组合数据类型(三):)