zoukankan      html  css  js  c++  java
  • 简述Orderdict,defaultdcit,ChainMap以及MappingProxyType

    先说下功能以及该模块来之哪个包

    Orderdict:有序字典,来至collections(好用)

    defaultdcit:为确实的键添加默认的值,来至collections(感觉非常实用)

    ChainMap:将多个字典映射到一个分组中,来至collections,(感觉有点鸡肋的功能)

    MappingProxyType:将字典转化成只读新式,来至types,(有意思。)

    先说Orderdict,前面实际操作中发现,除了字典生成式不能用,另外创建字典,获取信息,很多操作跟字典都是通用的。

    我尽量找一些它特有的方式,给自己加深印象。

    a = {'a': 2, 'b': 3, 'c': 4, 'd': 5, }
    o_d = OrderedDict()
    for k,v in a.items():
        o_d[k] = v
    print(o_d)
    print(type(o_d))
    print(o_d['a'])
    o_d['e'] = 5
    o_d['d'] = 8
    print(o_d)
    
    OrderedDict([('a', 2), ('b', 3), ('c', 4), ('d', 5)])
    <class 'collections.OrderedDict'>
    2
    OrderedDict([('a', 2), ('b', 3), ('c', 4), ('d', 8), ('e', 5)])

     先生成了一个有序字典,看了下格式,有点像列表里面套元祖的形式,进行了一些常规操作,跟字典一样。

    print(set(dir(o_d))-set(dir({})))
    {'__reversed__', '__dict__', 'move_to_end'}
    

     通过差集比较多了两个魔法方法,一个普通方法,吐血。。。。。

    b = o_d.__reversed__()
    print(next(b))
    print(list(b))
    o_d.__dict__['x'] = 123
    print(o_d)
    o_d.move_to_end('b')
    print(o_d)
    o_d.move_to_end('c',last=False)
    print(o_d)
    a,b = o_d.popitem()
    print(a,b)
    print(o_d)
    c,d = o_d.popitem(last=False)
    print(c,d)
    print(o_d)
    e
    ['d', 'c', 'b', 'a']
    OrderedDict([('a', 2), ('b', 3), ('c', 4), ('d', 8), ('e', 5)])
    OrderedDict([('a', 2), ('c', 4), ('d', 8), ('e', 5), ('b', 3)])
    OrderedDict([('c', 4), ('a', 2), ('d', 8), ('e', 5), ('b', 3)])
    b 3
    OrderedDict([('c', 4), ('a', 2), ('d', 8), ('e', 5)])
    c 4
    OrderedDict([('a', 2), ('d', 8), ('e', 5)])
    

     通过实际操作发现,__reversed__有一点作用,可以把字典的key进行排序,然后返回一个迭代器。

    __dict__没啥发现,感觉用不上,move_to_end可以通过输入key指定到最后,默认情况下,如果修改了last参数就到第一

    popitem也一样,默认弹出最后一组,修改弹出第一个。

    上次网上还看到一种比较帅气的取出有序字典的第一组数据。

    print(next(iter(o_d.items())))
    print(o_d)
    
    ('a', 2)
    OrderedDict([('a', 2), ('d', 8), ('e', 5)])
    

     这样就可以不修改原来参数的情况下,获取第一个字典元素的数据。

    下一个defaultdict,直接上代码:

    from collections import defaultdict
    dd = defaultdict(list)
    dd['aa'].append(123)
    dd['bb'].append('')
    print(dd)
    
    dd2 = dict.fromkeys('1234',[])
    print(dd2)
    dd2['1'].append(123)
    print(dd2)
    defaultdict(<class 'list'>, {'aa': [123], 'bb': ['']})
    {'1': [], '2': [], '3': [], '4': []}
    {'1': [123], '2': [123], '3': [123], '4': [123]}
    

     通过对比发现defaultdict还是非常好用的,他会再你生成新的key时,按照你的要求,已经开辟了一个独立空间存放了value

    对比了fromkeys,很早的时候我就用这个创建了一组字典,当时还想装逼,发现失败,这个生成后面的value如果是可变参数都指向同一个地址(不可变元素还时可以的)

    关于defautdict其实更加准确的来说,跟setdefault对比更加合适,setdefault是对一个字典取值,有的话就取值,没的话就添加一个键值对进去。

    其实defautdict,后面也可以通过=号的形式添加数据,如果读取到就返回数据,读取不到就把第一个参数执行变成value,key为取值的值,前面我填一个数据的时候,肯定每次取值都取不到,所以每次都给key生成一个list或[]的value

    其实参数[]换成list函数也可以,因为执行list[],也是生成一个空列表。所以第一个参数确切的是返回一个函数。

    from collections import defaultdict
    import time
    import random
    
    def choose():
        return random.randint(10,20)
    
    
    
    dd = {'name': 'sidian', 'sex': 'male'}
    print(dd.setdefault('addr', 'hangzhou'))
    print(dd.setdefault('age', choose()))
    print(dd)
    
    
    def r_time():
        return time.asctime()
    
    
    print('~' * 100)
    
    dd_default = defaultdict(r_time, hobby='watch_tv', **dd)  # 返回函数,第二参数解包前面的字典参数,也可以用=号
    print(dd_default['name'])    # 取值
    print(dd_default['hobby'])    #取值
    print(dd_default['time'])     #没有就赋值
    print(dd_default)
    print(dd_default['time'])
    
    '''这样测试来看,其实跟setdeault功能差不多,两者你想用哪个都可以。'''
    
    hangzhou
    18
    {'name': 'sidian', 'sex': 'male', 'addr': 'hangzhou', 'age': 18}
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    sidian
    watch_tv
    Fri Nov 15 04:06:46 2019
    defaultdict(<function r_time at 0x108b3c710>, {'hobby': 'watch_tv', 'name': 'sidian', 'sex': 'male', 'addr': 'hangzhou', 'age': 18, 'time': 'Fri Nov 15 04:06:46 2019'})
    Fri Nov 15 04:06:46 2019
    
    d_dict = defaultdict({'a':1, 'b':2})                                                                          
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-538-495985ac56c1> in <module>
    ----> 1 d_dict = defaultdict({'a':1, 'b':2})
    
    TypeError: first argument must be callable or None
    
    In [539]: d_dict = defaultdict(str,{'a':1, 'b':2})                                                                      
    
    In [540]: d_dict[12]                                                                                                    
    Out[540]: ''
    
    In [541]: d_dict                                                                                                        
    Out[541]: defaultdict(str, {'a': 1, 'b': 2, 12: ''})
    

     再次使用,其实defaultdict第一个参数一定要是一个可调用参数,或者None,后面可以写一些普通的字典创建的语法。

    读取这个对象时,有key就返回,没key就新建这个key位key,然后调用前面的函数,或者None,新建这组k,v,并返回这个函数的返回值或者None

    同setdefault效果差不多,都是肯定有返回值的。底层都应该调用了__missing__。

    ChainMap感觉挺鸡肋的函数,就是把两个字典合并了一下,可以找两个加起来的key,那直接uodate一下,返回一个新的扩展字典查找也不是一样吗?

    d1 = {1: 2, 3: 4}
    d2 = {3: 4, 4: 5, 5: 6}
    d3 = ChainMap(d1,d2)
    print(d3,type(d3))
    print(d3[3],d3[1])
    
    ChainMap({1: 2, 3: 4}, {3: 4, 4: 5, 5: 6}) <class 'collections.ChainMap'>
    4 2
    

     MappingProxyType将返回一个收保护只读的字典,有意思。

    from types import MappingProxyType
    
    d1 = {1: 2, 3: 4}
    d6 = MappingProxyType(d1)
    print(d6, type(d6), sep='===')
    d1[1] = 5
    print(d1)
    d6[1] = 5
    print(d6)
    
    {1: 2, 3: 4}===<class 'mappingproxy'>
    {1: 5, 3: 4}
    Traceback (most recent call last):
      File "/Users/shijianzhong/Desktop/bit_coin/test_file/temp.py", line 65, in <module>
        d6[1] = 5
    TypeError: 'mappingproxy' object does not support item assignment
    
  • 相关阅读:
    [USACO Mar08] 牛跑步 --k短路
    [ZJOI2008]树的统计Count
    [SDOI2010]魔法猪学院 --k短路
    POJ 2449 Remmarguts' Date -K短路
    [SCOI2007]kshort--k短路
    [HAOI2015]树上操作 -树链剖分
    HDU Aragorn's Story -树链剖分
    [USACO09JAN]安全出行Safe Travel
    2019全球区块链杭州高峰论坛将于5月17日举办!
    2019亚洲物联网安全创新国际峰会将于5月在上海开幕!
  • 原文地址:https://www.cnblogs.com/sidianok/p/11846440.html
Copyright © 2011-2022 走看看