python|4-2 无序性序列(字典,集合)|zip()函数简单介绍|可哈希类型 vs 不可哈希类型简单介绍

1、字典和集合与序列的区别

特性序列(strlisttuple字典(dict集合(set
有序性有序无序(Python 3.7+ 保持插入顺序)无序
索引访问支持不支持(通过键访问值)不支持
切片操作支持不支持不支持
元素唯一性不要求唯一键唯一元素唯一
用途存储有序数据存储键值对去重、集合运算

2、zip() 函数

        zip()函数是 Python 中的一个内置函数,用于将多个可迭代对象(如列表、元组、字符串等)“压缩” 成一个迭代器。它会将每个可迭代对象中相同位置的元素组合成元组,最终返回一个由这些元组组成的迭代器。

特性:惰性迭代器,与生成器类似

  1. 迭代器耗尽
    zip() 返回的是一个迭代器,遍历一次后会被耗尽。如果需要多次使用,可以将其转换为列表或元组。

  2. 长度不一致
    如果可迭代对象的长度不一致,zip() 会以最短的可迭代对象为准。

  3. 性能优化
    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) 的数据结构,具有以下特点:

  1. 无序性:字典中的键值对没有固定顺序(Python 3.7+ 中字典保持插入顺序,但仍不视为序列)。

  2. 通过键访问值:使用键来访问对应的值,如 dict[key]

  3. 唯一性:字典的键必须是唯一的。

  4. 可变性:字典是可变的,可以添加、删除或修改键值对。

字典的创建与删除

# (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

 若有错误,敬请批评指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值