字典和集合

字典

字典的key必须是可散列的数据类型,实现了__hash__()__qe__()方法。

字典推导

字典推导可以从任何以键值对作为元素的可迭代对象中构建出字典。

1
2
3
4
5
dial = [('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3'), ('key4', 'value4')]

dic = {key : value for key , value in dial}

print (dic)

setdefault

类似于collections.defaultdict,在查询不到key时不会抛出异常而是返回默认值。

1
2
3
4
5
dial = [('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3'), ('key4', 'value4')]

dic = {key : value for key , value in dial}

print (dic.setdefault('nokey', 'notfoundvalue')

__missing__

所有的映射类型在处理找不到的键时,都会牵扯到__missing__方法。基类dict虽然没有提供该方法,但是如果一个类继承了dict,并且提供__missing__方法,那么在__getitem__找不到键时便会自动调用__missing__方法。

1
2
3
4
5
6
7
8
9
10
11
class mydict(dict):
def __missing__(self, key):
self[key] = 'default'
print('调用missing方法')
return 'default'

test = mydict()
test['key'] = 'value'

print (test['key'])
print (test['nokey'])

另外__missing__方法只会被__getitem__调用,不会被get或者__contains__调用。

collections.OrderDict

添加键的时候会保持顺序,因此键的迭代次序可以保持一致。
popitem()方法默认删除最后一个添加的键值对,提供参数last=False时删除第一个。

collections.ChainMap

1
2
3
4
5
6
7
from collections import ChainMap

x = {'a': 1, 'b': 2}
y = {'b': 10, 'c': 11}
z = ChainMap(y, x)
for k, v in z.items():
print(k, v)

collections.UserDict

用纯Python的方式把标准的dict实现了一遍,提供给用户继承写子类。但collections.UserDict并不是dict的子类。

不可变映射类型

MappingProxyType可以返回一个只读的映射试图,并且是动态的。我们可以通过这个代理访问到源映射但是无法作出修改,从而保证了数据的安全性。

1
2
3
4
5
6
7
from types import MappingProxyType

dic = {"key":"value"}

dic_proxy = MappingProxyType(dic)
print(dic_proxy["key"])
dic_proxy["newkey"] = "newvalue"

字典的特点

  • 内存开销大,散列表是稀疏数组导致了大内存的开销。
  • 键查询速度快。
  • 往字典里添加新建可能会导致已有键的顺序改变。—-那么如何避免这个问题呢?

集合论

集合中的元素必须是可散列的,set类型本身是不可散列的。集合的本质是许多唯一对象的集合,因此集合可以用于去重。接受一个可迭代对象去掉重复部分。

1
2
set([1,2,3,4,5,6,6,5,4,3,2,1])
set("google")

中缀运算符:

  • | 合集
  • & 交集
  • - 差集
  • ^ 对称差
  • in 属于
  • <= 包含于
  • < 真包含于

集合推导

1
2
l = [1,2,3,4,5,6,6,5,4,3,2,1]
s = {i for i in l if i < 5}

集合的其他方法

  • s.add(e) 添加
  • s.clear() 清空
  • s.copy() 浅复制
  • s.discard(e) 移除,不存在不抛出异常
  • s.remove(e) 异常,不存在抛出异常
  • s.pop() 随机移除,不存在抛出异常

集合的特点

  • 元素必须是可散列的。
  • 内存开销大,由上一条特点导致。
  • 可以高效的判断元素是否存在某一个集合中。
  • 元素次序取决于添加次序
  • 添加新元素可能破坏原有次序。

散列表

  • 散列表是一个稀疏数组(总是有空白的数组称为稀疏数组)。散列值在理想情况下越是相似,他们的散列值差别越大。
  • 盐值:盐值是python进程中的一个常量,每次启动Python解释器生成的盐值都不相同。盐值主要用于计算对象的散列值。在计算散列值时随机加盐可以防止DOS攻击。
  • 散列表的算法:略
  • 可散列的条件:
    • 支持hash()函数,并且通过__hash__()方法得到的散列值是不变的(同一次启动解释器中不变,加盐的原因不同次不相等)
    • 支持通过__eq__()方法来检测相等性。
    • a == bhash(a) == hash(b)

本文标题:字典和集合

文章作者:Darren

发布时间:2018年09月12日 - 21:09

最后更新:2018年09月12日 - 21:09

原始链接:http://Darren2017.github.io/2018/09/12/字典和集合/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。