1、字典和集合与序列的区别
特性 | 序列(str , list , tuple ) | 字典(dict ) | 集合(set ) |
---|---|---|---|
有序性 | 有序 | 无序(Python 3.7+ 保持插入顺序) | 无序 |
索引访问 | 支持 | 不支持(通过键访问值) | 不支持 |
切片操作 | 支持 | 不支持 | 不支持 |
元素唯一性 | 不要求唯一 | 键唯一 | 元素唯一 |
用途 | 存储有序数据 | 存储键值对 | 去重、集合运算 |
2、zip() 函数
zip()函数是 Python 中的一个内置函数,用于将多个可迭代对象(如列表、元组、字符串等)“压缩” 成一个迭代器。它会将每个可迭代对象中相同位置的元素组合成元组,最终返回一个由这些元组组成的迭代器。
特性:惰性迭代器,与生成器类似
-
迭代器耗尽
zip()
返回的是一个迭代器,遍历一次后会被耗尽。如果需要多次使用,可以将其转换为列表或元组。 -
长度不一致
如果可迭代对象的长度不一致,zip()
会以最短的可迭代对象为准。 -
性能优化
zip()
是惰性求值的,适用于处理大型数据集。
将两个列表压缩:
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
zipped = zip(names, ages)
print(list(zipped)) # 输出: [('Alice', 25), ('Bob', 30), ('Charlie', 35)]
将三个列表压缩:
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["New York", "London", "Paris"]
zipped = zip(names, ages, cities)
print(list(zipped)) # 输出: [('Alice', 25, 'New York'), ('Bob', 30, 'London'), ('Charlie', 35, 'Paris')]
长度不一致的可迭代对象:
如果可迭代对象的长度不一致,zip()
会以最短的可迭代对象为准:
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30]
zipped = zip(names, ages)
print(list(zipped)) # 输出: [('Alice', 25), ('Bob', 30)]
解压缩:zip(*zipped)
zipped = [('Alice', 25), ('Bob', 30), ('Charlie', 35)]
names, ages = zip(*zipped)
print(names) # 输出: ('Alice', 'Bob', 'Charlie')
print(ages) # 输出: (25, 30, 35)
将两个序列压缩为字典
keys = ["name", "age", "city"]
values = ["Alice", 25, "New York"]
data = dict(zip(keys, values))
print(data) # 输出: {'name': 'Alice', 'age': 25, 'city': 'New York'}
3、可哈希类型 vs 不可哈希类型
特性 | 可哈希类型(Hashable Types) | 不可哈希类型(Unhashable Types) |
---|---|---|
定义 | 对象的值在其生命周期内不可改变,且实现了 __hash__() 和 __eq__() 方法。 | 对象的值在其生命周期内可以改变,通常未实现 __hash__() 方法。 |
是否可变 | 不可变 | 可变 |
是否可作为字典的键 | 可以 | 不可以 |
是否可作为集合元素 | 可以 | 不可以 |
常见类型 | - 整数(int )- 浮点数( float )- 字符串( str )- 元组( tuple )(元素可哈希) | - 列表(list )- 字典( dict )- 集合( set )- 自定义可变对象 |
示例 | python<br>d = {1: "one", "key": "value", (1, 2): "tuple"}<br>s = {1, 2, 3, "hello"}<br> | python<br>d = {[1, 2]: "list"} # 报错<br>s = {{1, 2}} # 报错<br> |
自定义对象 | 需要实现 __hash__() 和 __eq__() 方法,且对象不可变。 | 默认不可哈希,除非显式实现 __hash__() 和 __eq__() 方法,并确保对象不可变。 |
4、字典
字典(dict
)的特性
字典是一种键值对(key-value pair) 的数据结构,具有以下特点:
-
无序性:字典中的键值对没有固定顺序(Python 3.7+ 中字典保持插入顺序,但仍不视为序列)。
-
通过键访问值:使用键来访问对应的值,如
dict[key]
。 -
唯一性:字典的键必须是唯一的。
-
可变性:字典是可变的,可以添加、删除或修改键值对。
字典的创建与删除
# (1)使用{key:value}创建字典
d={10:'cat',20:'dog',30:'pet',20:'zoo'}
print(d) # 键相同时,value值进行更新
# (2) zip()函数
lst1=[1,2,3,4]
lst2=['hello','world','sdf','python']
zipobj=zip(lst1,lst2)
print(zipobj,type(zipobj))
print(list(zipobj)) #已经遍历了一次 [(1, 'hello'), (2, 'world'), (3, 'sdf'), (4, 'python')]
d=dict(zipobj) # ......
print(d,type(d)) # {} <class 'dict'>
# zip()是一个惰性迭代器,在被遍历一次后,其中的内容会耗尽
# 想要多次使用,需将其先转换为元组或字典
# 使用参数创建字典
d=dict(cat=10,dog=20)
print(d,type(d))
t=(12,23,34) # tuple
print({t:10}) # {(12,23,34):10} t是key,10是value,元组可以作为字典中的key
# lst=[10,20,30] #列表
# print({lst:10}) #TypeError: unhashable type: 'list',见第3小节
# 字典属于序列
print('max:',max(d))
print('min:',min(d))
print('len:',len(d))
# 字典的删除
# del d
# print(d) #NameError: name 'd' is not defined
输出结果:
{10: 'cat', 20: 'zoo', 30: 'pet'}
<zip object at 0x00000239BCE4B140> <class 'zip'>
[(1, 'hello'), (2, 'world'), (3, 'sdf'), (4, 'python')]
{} <class 'dict'>
{'cat': 10, 'dog': 20} <class 'dict'>
{(12, 23, 34): 10}
max: dog
min: cat
len: 2
字典元素的访问与遍历
d={'hello':10,'world':20,'python':30}
# 访问字典中的元素
# (1) 使用d[key]
print(d['hello'])
# (2) d.get(key) 获取key对应的值
print(d.get('hello'))
# 二者是有区别的,如果key不存在,d[key]会报错,d.get(key)可以指定默认值
# print(d['jave']) # keyerror: 'java'
print(d.get('jave')) # None
print(d.get('jave','不存在'))
# 字典的遍历
for item in d.items():
print(item,end='\t') # (key,value)组成的一个元素
print()
# 使用for循环遍历时,分别获取key,value
for key,value in d.items():
print('key','-->',value,end='\t')
输出结果:
10
10
None
不存在
('hello', 10) ('world', 20) ('python', 30)
key --> 10 key --> 20 key --> 30
字典的相关操作
d={1001:'赛文',1002:'赛罗',1003:'时王'}
print(d)
# 向字典添加元素
d[1004]=('海绵宝宝') # 直接使用赋值运算符向字典中添加元素
print(d)
print('-'*50)
# 获取字典中所有的key
keys=d.keys()
print(keys,type(keys)) # 字典键类型,dict_keys(['1001', '1002', '1003', 1004]) <class 'dict_keys'>
print(list(keys)) # 转成列表[,,,]
print(tuple(keys)) # 转成元组(,,,)
print('-'*50)
# 获取字典中所有的value
values=d.values()
print(values,type(values))
print(list(values))
print(tuple(values))
print('-'*50)
# 将字典中的数据转换为key-value的形式,以元组的方式进行展现,一个键值对就是一个元组
lst=list(d.items())
print(lst)
print('-'*50)
d=dict(lst)
print(d)
print(d.pop(1001)) # 移除1001
print(d)
print(d.pop(1008,'不存在')) # 更改默认值
print('-'*50)
# 随机删除
# d.popitem() 用于移除并返回字典中的最后一个键值对。
# 如果字典为空,popitem() 会抛出 KeyError。
print(d.popitem(),type(d.popitem())) # (1004, '海绵宝宝') <class 'tuple'>
print(d) # {1002: '赛罗', 1003: '时王'}
print('-'*50)
# 清空字典所有的元素
d.clear()
print(d)
print('-'*50)
# python中的一切都是对象,每个对象都有一个布尔值
print(bool(d)) # 空字典的bool值为False
输出结果:
{1001: '赛文', 1002: '赛罗', 1003: '时王'}
{1001: '赛文', 1002: '赛罗', 1003: '时王', 1004: '海绵宝宝'}
--------------------------------------------------
dict_keys([1001, 1002, 1003, 1004]) <class 'dict_keys'>
[1001, 1002, 1003, 1004]
(1001, 1002, 1003, 1004)
--------------------------------------------------
dict_values(['赛文', '赛罗', '时王', '海绵宝宝']) <class 'dict_values'>
['赛文', '赛罗', '时王', '海绵宝宝']
('赛文', '赛罗', '时王', '海绵宝宝')
--------------------------------------------------
[(1001, '赛文'), (1002, '赛罗'), (1003, '时王'), (1004, '海绵宝宝')]
--------------------------------------------------
{1001: '赛文', 1002: '赛罗', 1003: '时王', 1004: '海绵宝宝'}
赛文
{1002: '赛罗', 1003: '时王', 1004: '海绵宝宝'}
不存在
--------------------------------------------------
(1004, '海绵宝宝') <class 'tuple'>
{1002: '赛罗'}
--------------------------------------------------
{}
--------------------------------------------------
False
字典生成式
import random
d={item:random.randint(1,100) for item in range(4)}
print(d)
# 创建两个列表
lst=[1,2,3]
lst2=['张三','李四','王五']
# 使用zip() 函数合并两个列表
"""
zipped=zip(lst,lst2) -->
lst=list(zipped) --> 元素为元组的列表 [(1,'张三'),(2,'李四')(3,'王五')]
d=dict(lst) --> 字典{1:'张三',2:'李四',3:'王五'}
"""
d={key:value for key,value in zip(lst,lst2)}
print(d)
print(list(d.items()))
print(tuple(d.items()))
输出结果:
{0: 68, 1: 44, 2: 13, 3: 5}
{1: '张三', 2: '李四', 3: '王五'}
[(1, '张三'), (2, '李四'), (3, '王五')]
((1, '张三'), (2, '李四'), (3, '王五'))
合并字典的运算符
d1={'a':10,'b':20}
d2={'c':30,'d':40,'e':50}
merged_dict=d1|d2 #并集操作
print(merged_dict)
{'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': 50}
5、集合
集合的创建与删除
# 使用{}创建集合
s={1,2,3,4}
print(s)
# 集合只能存储不可变数据类型
# s={[1,2],[3,4]}
# print(s) # TypeError: unhashable type: 'list'
# 使用set()创建集合
s=set() # 创建了一个空集合,空集合的bool值是False
print(s,bool(s))
s={} # 创建的是字典
print(s,type(s))
s=set('helloworld') # 集合是无序的
print(s) # {'o', 'r', 'd', 'e', 'w', 'h', 'l'} ,每次输出的结果可能不一样
s2=set([1,2,3])
print(s2) # {1, 2, 3}
s3=set(range(10))
print(s3)
# 集合像字典一样,都是序列中无序的类型
print('max():',max(s3))
print('min():',min(s3))
print('len():',len(s3))
print('9在s3中吗?',9 in s3)
print('9b不在s3中吗?',9 not in s3)
# 集合的删除
del s3
# print s3 # print(s3) # NameError: name 's3' is not defined
输出结果:
{1, 2, 3, 4}
set() False
{} <class 'dict'>
{'o', 'r', 'd', 'e', 'w', 'h', 'l'}
{1, 2, 3}
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
max(): 9
min(): 0
len(): 10
9在s3中吗? True
9b不在s3中吗? False
集合的操作符|并集|、交集&、差集-、补集^
A={1,2,3,4,5}
B={23,4,3,65,567}
# 交集操作
print(A&B)
# 并集操作
print(A|B)
# 差集操作
print(A-B)
print(B-A)
# 补集操作
print(A^B)
输出结果:
{3, 4}
{1, 2, 3, 4, 5, 65, 23, 567}
{1, 2, 5}
{65, 23, 567}
{65, 1, 567, 2, 23, 5}
集合的相关操作|遍历|生成式
s={12,34,56}
# 添加元素 .app()
s.add(124)
print(s)
# 删除元素 .remove()
s.remove(12)
print(s)
# 清空所有元素 .clear()
# s.clear()
# print(s)
# 集合的遍历操作
for items in s:
print(items,end='\t')
print()
# 使用enumerate()函数
for index,item in enumerate(s,start=4):
print(index,'-->',item,end='\t')
print()
# 集合的生成式
s={i for i in range(10)}
print(s)
for i in s:
print(i,end='\t')
输出结果:
{56, 124, 34, 12}
{56, 124, 34}
56 124 34
4 --> 56 5 --> 124 6 --> 34
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
0 1 2 3 4 5 6 7 8 9
若有错误,敬请批评指正