您的位置:首页 > 其它

about dict

2015-10-28 16:04 281 查看

the method __missing__

>>>from collections import defaultdict
>>>d = defaultdict(list)
>>>d['a'].append(1)
>>>d['b'].append(2)

>>>d

defaultdict(<class 'list'>, {'b': [2], 'a': [1]})

>>>d.get('c',None)

>>>d['c']

[]


在defaultdict内部究竟发生了什么?

这要从字典内部的__missing__方法说起。

__missing__只由__getitem__方法调用。

一旦__getitem__找不到了key,这时候__missing__便被调用。

可想而知,在difaultdict_factory中的__missing__方法里,调用了list(),并把结果赋值给了d[key]。

search dict.keys()

A search like k in my_dict.keys() is efficient in Python 3 even

for very large mappings because dict.keys() returns a view,

which is similar to a set, and containment checks in sets are as

fast as in dictionaries. Details are documented in the “Dictionary”

view objects section of the documentation. In Python 2,

dict.keys() returns a list, so our solution also works there, but

it is not efficient for large dictionaries, because k in my_list

must scan the list.

不同的dict

collections.OrderedDict

有序字典,字典可以记住插入的顺序,在迭代的时候先访问先插入的,最后访问最后插入的。

The popitem method of an OrderedDict pops the first item by default, but if called as my_odict.popitem(last=True), it pops the last item added.

collections.ChainMap

当你输入一个key,chainmap逐次搜索各个map中的值,直到存在并返回。

当你修改一个key-value时,只修改第一个map中的key-value对。

>>>import collections
>>>cmap =  collections.ChainMap() # 创建chainMap():空的{}

>>>a = {'a':1}
>>>b = {'b':2}
>>>cmap.new_child(a) # 增加新的map, 并创建新的ChainMap

ChainMap({'a': 1}, {})

>>>cmap   #原来的cmap未变

ChainMap({})

>>>cmap.update(a)

>>>cmap

ChainMap({'a': 1})

>>>cmap.update(b)

>>>cmap

ChainMap({'b': 2, 'a': 1})

>>>cmap.parents

ChainMap({})

>>>cmap1 = collections.ChainMap(a,b)

>>>cmap1

ChainMap({'a': 1}, {'b': 2})

>>>cmap1['b'] = 3    # 只修改a中的
>>>cmap1

ChainMap({'b': 3, 'a': 1}, {'b': 2})

>>>'c' in cmap1

False

>>>cmap1['b'] # 第一个出现的 'b'

3


collections.Counter

Counter统计可迭代对象中每个元素的出现次数,但是每个元素都必须是hashable的。

>>>counter = collections.Counter('abracadabra')
>>>counter

Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})

>>>counter.update('aaaaazzz')
>>>counter

Counter({'a': 10, 'z': 3, 'b': 2, 'r': 2, 'c': 1, 'd': 1})

>>>counter.most_common(2)

[('a', 10), ('z', 3)]


collections.UserDict

A pure Python implementation of a mapping that works like a standard dict.

这个专门是用来作为父类,被继承使用的。

其与dict的一大不同是,UserDict将自己的数据暴露出来,直接用self.data便能直接访问, self.data是字典。

比如,一组数据中有int,str(int)类型作为key都要进行查询访问,我们可以利用UserDict创建当前环境下适合的字典结构。

class StrDict(collections.UserDict):
def __missing__(self, key):
if isinstance(key, str):
raise KeyError(key)
return self[str(key)]

def __contains__(self, key):
return str(key) in self.data

def __setitem__(self, key, value): # watch out forever recursion by self[str[key]] = value
self.data[str(key)] = value

>>>sdict = StrDict()
>>>sdict['4'] = 'four'
>>>sdict[5] = 'five'
>>>sdict[1] = 'one'

>>>print(sdict[4])
four
>>>print(sdict['5'])
five
>>>print(sdict['1'])
one

>>>4 in sdict

True

>>>'5' in sdict

True

>>>6 in sdict

False


我们看一看继承关系StrDict->UserDict->MutableMapping->Mapping

>>>sdict.update(((2,'two'),(10,'ten')))  # inherited from MutableMapping.update

>>>sdict

{'10': 'ten', '4': 'four', '2': 'two', '5': 'five', '1': 'one'}

>>>sdict.get('5',None)  # inherited from Mapping.get

'five'

>>>print(sdict.get('9',None))

None


MutableMapping.update

This powerful method can be called directly but is also used by __init__ to load

the instance from other mappings, from iterables of (key, value) pairs, and keyword

arguments. Because it uses self[key] = value to add items, it ends up calling

our implementation of __setitem__.

Mapping.get

In StrKeyDict, we had to code our own get to obtain results consistent

with __getitem__, but in Example 3-8 we inherited Mapping.get, which is

implemented exactly like StrKeyDict0.get.

Immutable Mappings

The mapping types provided by the standard library are all mutable, but you may need

to guarantee that a user cannot change a mapping by mistake.

Since Python 3.3, the types module provides a wrapper class called MappingProxyType, which, given a mapping, returns a mappingproxy instance that is a read-only but

dynamic view of the original mapping. This means that updates to the original mapping can be seen in the mappingproxy, but changes cannot be made through it.

>>>import types
>>>d = {'a':1}
>>>d_proxy = types.MappingProxyType(d)

>>>d_proxy

mappingproxy({'a': 1})

>>>d_proxy['a'] = 2

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-43-00aea5d4359e> in <module>()
----> 1 d_proxy['a'] = 2

TypeError: 'mappingproxy' object does not support item assignment

>>>d['b'] = 2

>>>d_proxy  # dynamic linked

mappingproxy({'b': 2, 'a': 1})

>>>sdict.__dict__

{'data': {'1': 'one', '10': 'ten', '2': 'two', '4': 'four', '5': 'five'}}

>>>sdict.__dict__['m'] = 7

>>>sdict

{'10': 'ten', '4': 'four', '2': 'two', '5': 'five', '1': 'one'}

>>>sdict.__dict__

{'data': {'1': 'one', '10': 'ten', '2': 'two', '4': 'four', '5': 'five'},
'm': 7}

>>>sdict.m

7
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: