5.深入set和dict

1. dict的abc继承关系

dict继承自MutableMapping

>>> from collections.abc import Mapping, MutableMapping

>>> print(isinstance(dict, MutableMapping))  # isinstance判断  得是实例
False

>>> a = {}
>>> print(isinstance(a, MutableMapping))
True

2. dict的常用方法

>>> a = {'cannon1': {'company': 'company1'}, 'cannon2': {'company': 'company2'}}

# copy 返回浅拷贝
>>> new_dict1 = a.copy()
>>> new_dict1['cannon1']['company'] = 'copy'
>>> print(new_dict1)
{'cannon1': {'company': 'copy'}, 'cannon2': {'company': 'company2'}}
>>> print(a)
{'cannon1': {'company': 'copy'}, 'cannon2': {'company': 'company2'}}

# deepcopy 深拷贝
>>> import copy
>>> new_dict2 = copy.deepcopy(a)
>>> new_dict2['cannon2']['company'] = 'deepcopy'
>>> print(new_dict2)
{'cannon1': {'company': 'copy'}, 'cannon2': {'company': 'deepcopy'}}

>>> print(a)
{'cannon1': {'company': 'copy'}, 'cannon2': {'company': 'company2'}}

# clear
>>> a.clear()
>>> print(a)
{}


# fromkeys方法的使用
>>> new_list = ['cannon1', 'cannon2']
>>> new_dict = dict.fromkeys(new_list, {'company':'company3'})
>>> print(new_dict)
{'cannon1': {'company': 'company3'}, 'cannon2': {'company': 'company3'}}


# items
>>> for key, value in new_dict.items():
>>>     print(key)
cannon1
cannon2


# setdefault   会做两件事:1.把新设置的值取出来 2.更新原数据
>>> defaultvalue = new_dict.setdefault('cannon3', 'defaultvalue')
>>> print(defaultvalue)
defaultvalue
>>> print(new_dict)
{'cannon1': {'company': 'company3'}, 'cannon2': {'company': 'company3'}, 'cannon3': 'defaultvalue'}

# update 合并字典
>>> new_dict.update(cannon4='update1', cannon5='update2')
>>> new_dict.update((('cannon6','update3'), ('cannon7','update4'),))
>>> new_dict.update({'cannon8':'update5', 'cannon9':'update6'})
>>> print(new_dict)
{'cannon1': {'company': 'company3'}, 'cannon2': {'company': 'company3'},
'cannon3': 'defaultvalue', 'cannon4': 'update1', 'cannon5': 'update2',
'cannon6': 'update3', 'cannon7': 'update4', 'cannon8': 'update5', 'cannon9': 'update6'}

python 深浅拷贝的补充说明:

假如 a = [1, 2, 3, [0,0,0]]

1. =:       a=b a,b完全一样

2.浅拷贝:    b=copy.copy(a) , b是否随a改变而改变,视情况而定

            a,b内存地址不一样,但内存中(ab各自对应的列表中)各元素的内存地址是一样的。
            
            如果a[0]=2 , b不会跟随a改变。 因为a[0]中的1属于数字,是不可变元素,值改变内存也改变
            
            如果a[3].append(3) ,b会跟随a改变。因为列表是可变元素,增加一个值不会把a[3]这个列表的内存地址改变。而b[3]和a[3]所对应的列表的内存地址是一样的

3.深拷贝:    b=copy.deepcopy(a) , b永远不会因为a改变而改变

            a,b内存地址不一样,但内存中(ab各自对应的列表中)各元素,如果是不可变元素的,内存地址一样, 如果是可变元素的,内存地址不一样。这里a[3]和b[3]内存地址不一样
            
            如果a[0]=2 , b不会跟随a改变。 因为a[0]中的1属于数字,是不可变元素,值改变内存也改变
            
            如果a[3].append(3) ,b不会跟随a改变。因为列表是可变元素,增加一个值不会把a[3]这个列表的内存地址改变。而b[3]和a[3]所对应的列表的内存地址是不一样的,只是列表内的值一样,a[3]的变化不会改变b[3]

3. dict的子类

不建议继承list和dict

# 不建议继承dict
>>> class Mydict(dict):
>>>     def __setitem__(self, key, value):
>>>         super(Mydict, self).__setitem__(key, value * 2)


>>> my_dict = Mydict(one=1)   # 重写无效
>>> print(my_dict)   
{'one': 1}
>>> my_dict['one'] = 1       # 重写后用[]方法存放的值 才会调用重写的__setitem__
>>> print(my_dict)
{'one': 2}


# 如果想继承dict 就继承UserDict
>>> from collections import UserDict

>>> class Mydict(UserDict):
>>>     def __setitem__(self, key, value):
>>>         super(Mydict, self).__setitem__(key, value * 2)

>>> my_dict2 = Mydict(one=1)
>>> print(my_dict2)
{'one': 2}

# defaultdict   查询不存在的keyvalue时, 会默认返回{}
>>> from collections import defaultdict

>>> my_dict3 = defaultdict(dict)
>>> my_value = my_dict3['cannon']
>>> print(my_value)
{}

4. set和frozenset

set性能很高,实际操作中非常有用

#  set集合  fronzenset不可变集合,无序不重复
>>> s = set('abcd')   # 出入的必须是可迭代对象
>>> s = set(['a', 'b', 'c', 'd', 'e'])
>>> print(s)
{'b', 'c', 'e', 'd', 'a'}


# 初始化方法
>>> s1 = {'a', 'b', 'c'}
>>> s1.add('d')
>>> print(s1)
{'a', 'c', 'd', 'b'}

# frozenset    作用  可以作为dictkey
>>> s2 = frozenset('abcde')   # 设置好以后  不可变, 没有add等方法
>>> print(s2)
frozenset({'a', 'd', 'c', 'e', 'b'})

# set添加数据
>>> another_set = set('def')
>>> s3 = {'a', 'b', 'c'}
>>> s3.update(another_set)
>>> print(s3)
{'a', 'c', 'd', 'e', 'f', 'b'}

# 差集
>>> re_set = s3.difference(another_set)   # 等价于 re_set = s3 - another_set
>>> print(re_set)
{'a', 'c', 'b'}

>>> re_set1 = s & another_set   # 交集
>>> print(re_set1)
{'d', 'e'}

>>> re_set2 = s | another_set   # 并集
>>> print(re_set2)
{'a', 'c', 'd', 'e', 'f', 'b'}

# 是否是另一个集合的一部分
>>> print(re_set1.issubset(re_set2))   # re_set1   re_set_2的一部分
True

5. dict和set的实现原理

dict与list比较:
dict 性能远远高于list
list 中查找元素。会随list的增大而增大
dict 中查找元素。不会随dict的增大而增大
dict的特点:
1. dict的key必须是可哈希的
不可变的对象都是可哈希的,str, frozenset, tuple  自己实现的__hash__
2. dict内存花销大,但是查询速度快。 自己定义的对象或者python内部的对象都是用dict包装的
3. dict的存储顺序和元素添加顺序有关
4. 添加数据有可能改变已有数据的顺序

set 和 dict 的存储特点一样 都是基于哈希hash的




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值