十一、字典
当我们的数据量很大,查找一个元素使用索引不好用的时候, 可以利用 字典 (字典以键值对的形式存储, 通过键查找)
python 的字典 在很多地方也成为 哈希。有些地方称之为关系数组。
字典是 python 唯一的一个 【映射类型】, 字典不支持下标操作!!!
我使用两个列表也可以实现这种映射:
brand = ['李宁', '耐克', '光子']
slogan = ['一切皆有可能', 'Just do it ', '用心创造快乐']
print('光子的口号是:', slogan[brand.index('光子')]
输出 : 光子的口号是: 用心创造快乐
但是这样看起来繁琐, 而且容易出错,效率又低。
而使用字典 :
dict_brand_slogan = {'李宁': '一切皆有可能', '耐克': 'Just do it ', '光子': '用心创造快乐'}
print('光子的口号是:', dict_brand_slogan['光子']) 光子的口号是: 用心创造快乐
字典的用法 :
print(dir(dict))
输出 :
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__',
'__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__',
'__sizeof__', '__str__', '__subclasshook__',
'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
1. dict() 方法,用于【创建字典】。 将一个映射关系转换成字典。只接受一个参数(映射类型)
print(dict()) {}
print(dict(((1, 'xiaoming'), (2, 'xiaohong'), (3, 'xiaolv')))) {1: 'xiaoming', 2: 'xiaohong', 3: 'xiaolv'}
也可以使用【给dict传递关键字参数】的方式创建字典。关键字就是字典的 键, 关键字对应的值就是字典的值。
【注意】: 这种创建方式下, 关键字参数不能是一个常量(比如字符串)
dict1 = dict(name='xiaoming', age=15, sex='man')
print(dict1) {'name': 'xiaoming', 'age': 15, 'sex': 'man'}
print(type(dict1)) <class 'dict'>
2. 使用工厂函数创建字典。
【工厂函数】: 我们把一些值传递给函数, 函数会用这些值产生某种类型的对象作为结果返回。就像 我把一堆塑料放到玩具工厂,
最终会得到一个玩具一样, 我把一些映射关系传递给 dict 这个工厂函数, 他就会给我产生一个 字典。
像 str() 、 int() 、 list() 、 tuple() ... 都属于工厂函数。
3. fromkeys() 方法,接收两个参数 , 第一个为可迭代对象,生成字典的 键 , 第二个生成字典所有的键的值 。如果第二个没有提供,则用 None 代替。
print(dict.fromkeys((1,2))) {1: None, 2: None}
print(dict.fromkeys((1,2), ('小明', 'xiaohong'))) {1: ('小明', 'xiaohong'), 2: ('小明', 'xiaohong')}
dict1 = dict.fromkeys((1, 2), '棒棒哒')
print(dict1) {1: '棒棒哒', 2: '棒棒哒'} 生成了一个字典
print(dict1.fromkeys((1, ), '不行呀')) {1: '不行呀'} 我想仅仅将字典中某一个键的值替换掉, 发现不可以,只能删除一个新的字典
print(dict1) {1: '棒棒哒', 2: '棒棒哒'} 原来的字典并没有被修改
dict1['1'] = '好腻害' 我直接提供字典的键重新给字典赋值
print(dict1) {1: '棒棒哒', 2: '棒棒哒', '1': '好腻害'} 修改成功
4.keys() 获取字典中所有的 键
dict1 = {'name': 'xiaoming', 'age': 15}
print(dict1.keys()) dict_keys(['name', 'age'])
5. values() 获取字典中所有的 值
dict1 = {'name': 'xiaoming', 'age': 15}
print(dict1.values()) dict_values(['xiaoming', 15])
6. get(key,defaul=None) 获取字典中某个键对应的值,接收两个参数, 第二个默认值为 None,
如果在字典中没有找到 我们要的 key , 就返回第二个参数。
dict1 = {'name': 'xiaoming', 'age': 15}
print(dict1.get('name')) xiaoming
print(dict1.get('sex')) None
print(dict1.get('sex', 'man')) man
判断一个键是否在字典中还可以用 in 和 not in 来进行
dict1 = {'name': 'xiaoming', 'age': 15}
print('name' in dict1) True
print('sex' in dict1) False
7. clear() 清空字典
如下, 我想要清空一个字典, 很容易写到的办法就是给这个字典对应的变量重新赋值为一个空字典。
但是, 这样做只是相当于把贴在旧字典上面的标签贴到了另外一个地方, 如果我旧的字典还贴了其他的标签,
那么访问其他的标签得到的还是旧的字典!!! 所以我们应该使用 clear() 这个函数来清空旧的字典,
而不是把标签贴到新的字典上面去!!!!
dict1 = {'name': 'xiaoming', 'age': 15}
dict2 = dict1 把标签 dict2 也贴到字典 {'name': 'xiaoming', 'age': 15} 上面
print(dict2) {'name': 'xiaoming', 'age': 15}
dict1 = {} 把 标签 dict1 贴到别的地方
print(dict1) {} 标签 dict1 的值变了
print(dict2) {'name': 'xiaoming', 'age': 15} 标签 dict2 的值还没变(这就可能引发 BUG )
dict3 = dict2 把标签 dict3 也贴到字典 {'name': 'xiaoming', 'age': 15} 上面
print(dict3) {'name': 'xiaoming', 'age': 15}
dict2.clear() 调用 clear() 方法清空 标签 dict2 对应的字典
print(dict2) {} 标签 dict2 的值变了
print(dict3) {} 标签 dict3 的值也跟着变了
8. copy() 浅拷贝
如下, 使用赋值只是给原变量对应的值多贴了一个标签, 在内存中这两个标签指向同一块内存。
而使用 copy() 函数得到的是在内存中分配的另外一个值,他有自己独立的内存。
dict1 = {'name': 'xiaoming', 'age': 15}
dict2 = dict1
dict3 = dict1.copy()
print(id(dict1)) 1844290215512
print(id(dict2)) 1844290215512
print(id(dict3)) 1844290215584
9. pop(key) 给定键, 弹出对应的【值】。如果给的键在字典中不存在, 则会抛出一个异常 : KeyError: 'sex'
pop 可以用来删除字典中指定的元素, pop 必须指定一个键, 否则报 TypeError: pop expected at least 1 arguments, got 0
dict1 = {'name': 'xiaoming', 'age': 15}
print(dict1.pop('name')) xiaoming
print(dict1) {'age': 15}
print(dict1.pop('sex')) KeyError: 'sex'
print(dict1.pop() TypeError: pop expected at least 1 arguments, got 0
10. popitem() 随机弹出字典中的一个项 【键和值都弹出来】
dict1 = {'name': 'xiaoming', 'age': 15, 'sex': 'man'}
print(dict1.popitem()) ('sex', 'man')
print(dict1) {'name': 'xiaoming', 'age': 15}
11. setdefault(key, value=None) 可以用来给字典添加一个新的键值对,如果添加的键已经存在了, 那么本次操作无效。
返回添加的键对应的值 。 比如, 我要在字典中查找某个键对应的值, 如果没找到, 我就把这个键添加进去,并且给一个默认值。
dict1 = {'name': 'xiaoming', 'age': 15, 'sex': 'man'}
dict1.setdefault('name', 'laowang') 想把 name 设置为 laowang
print(dict1.setdefault('name', 'laowang')) xiaoming 这里打印出小明, 什么字典里面已经有 name 这个键
print(dict1.setdefault('dalao', '客气客气')) 客气客气 这里打印的是 默认值, 说明原字典没有这个键或者原来这个键的值就是 客气客气
dict1.setdefault('小白') 这里没有给 键 设置值, 所以他的值就使用了默认的 None
print(dict1) {'name': 'xiaoming', 'age': 15, 'sex': 'man', 'dalao': '客气客气', '小白': None}
12. update() 使用一个新的字典或者一个映射关系去跟新一个字典。如果新的字典或者映射关系里面的 键 在老的字典里已经存在,
那么 就用新的值替换老的值, 如果不存在, 那么就把这个新的键值对添加到老的字典里面。
可以用来一次性给字典添加多个元素
dict1 = {'name': 'xiaoming', 'age': 15, 'sex': 'man'}
dict1.update({'name': 'laowang'})
print(dict1) {'name': 'laowang', 'age': 15, 'sex': 'man'}
dict1.update({'dalao?': 'yes'})
print(dict1) {'name': 'laowang', 'age': 15, 'sex': 'man', 'dalao?': 'yes'}
十二、 集合
集合里面的每个元素都是唯一的。集合也是无序的,不能去试图索引集合中的某一个元素。
set1 = {1, 2, 3, 4, 4, 3, 2, 1}
print(set1) {1, 2, 3, 4} 相同的元素只保留了一个
print(type(set1)) <class 'set'>
print(set1[1]) TypeError: 'set' object does not support indexing
集合的用法 :
print(dir(set))
['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__',
'__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__',
'__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__',
'__subclasshook__', '__xor__',
'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update',
'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update',
'union', 'update']
1. 创建集合 :
方法一、 直接用一个花括号将右对元素括起来(用逗号隔开)
方法二、使用 set() 这个工厂函数。传入一个可迭代对象 (比如字典、元组、字符串)
set() 函数可以用于列表等的去重。 但是 set 创造的集合是无序的!!!
print(set([1, 2, 3, 5, 5])) {1, 2, 3, 5}
print(set('hello')) {'h', 'o', 'l', 'e'}
2. 可以用 in 和 not in 判断一个元素是否在集合中。
print(5 in set([1, 2, 3, 5, 5, 4])) True
print('hello' in set([1, 2, 3, 5, 5, 4])) False
3. add() 方法 : 往集合添加一个元素
set1 = {1, 2, 3, 4, 4, 3, 2, 1}
print(set1) {1, 2, 3, 4}
set1.add(10)
print(set1) {1, 2, 3, 4, 10}
4. remove() 方法 : 移除集合中的一个元素(要移除的元素不存在就会报错 KeyError: 5)
set1.remove(4)
print(set1) {1, 2, 3, 10}
----------------------
十三 、 不可变集合 【 frozenset 】
set2 = frozenset([1, 5, 6, 7, 8, 6, 5])
print(set2) frozenset({1, 5, 6, 7, 8})
set2.add('hehe') AttributeError: 'frozenset' object has no attribute 'add'