zoukankan      html  css  js  c++  java
  • 6

    1 字典介绍

            在Python中字典属于一种映射类型,它和set相同,同样属于非线性结构存储,Python官方对dict有如下解释

    • 一个映射对象映射一个可hash的值到任意一个对象上去。
    • 映射是可变的对象。
    • dict是当前唯一一个标准的映射类型。
    • 字典的键几乎可以任意的值。
    • 字典的值可以不必可hash,也就是说值可以是列表,字典,或者其他任意可变的对象
    • 如果key相同,那么后面的value将会覆盖先前的value
    • 不建议使用float类型作为字典的key

    简单来说:字典是由key:value键值对组成的数据的集合,它的主要特点是 可变的无序的不重复的

    字典的key必须是可hash对象。

    2 字典的基本操作

            字典是除set集合以外另一种可变的非线性容器模型,在Python中非常强大,适合各种结构数据的存储、嵌套等。

    2.1 字典的定义

            字典的每个key到value的键值对用冒号(:)分割,每对之间用逗号(,)分割,整个字典包括在花括号({})中。例:{'a':1, 'b':2},Python提供了多种创建字典的方式,如下:

    • 基本格式:d = dict() 或者 d = {}
    • dict(**kwargs): 使用name=value对,来初始化一个字典
    • dict(iterable, **kwargs):使用可迭代对象和name=value构造字典,注意可迭代对象必须是一个二元结构
    • dict(mapping, **kwargs): 使用一个字典构造另一个字典
    • dic = {'a':1, 'b':2, 'c':3, 'd':[1,2,3]}
    • dic = dict.fromkeys(iterable, value): 使用可迭代对象的值作为key生成字典,value默认为0,否则用指定的value对字典进行初始化。
    In [114]: d1=dict()                                                                                        
    In [115]: d2={}                                                                                            
    In [118]: d3 = dict(a=1,b=2)                                                                               
    In [120]: d3                                                                                               
    Out[120]: {'a': 1, 'b': 2}
    In [124]: d4 = dict([('a',1),('b',2)], c=3, d=4)                                                           
    In [125]: d5 = dict(d4,e=5,f=6)                                                                            
    In [126]: d7 = dict.fromkeys(range(5))                                                                     
    In [127]: d8 = dict.fromkeys(range(5),100)                                                                
    In [128]: d7                                                                                               
    Out[128]: {0: None, 1: None, 2: None, 3: None, 4: None}                                                         
    In [131]: d8                                                                                               
    Out[131]: {0: 100, 1: 100, 2: 100, 3: 100, 4: 100} 
    

    2.2 字典元素的访问

    有如下三种方式访问字典的键值对:

    • d[key]: 返回key对应的value,key不存在抛出KeyError异常
    • dict.get(key[, default]): 返回key对应的value,key不存在返回缺省值,如果没有设置缺省值赶回None
    • dict.setdefault(key[, default]): 返回key对应的值value,key不存在,添加key:value键值对(value设置为default),并返回value,如果default没有设置缺省为None
    In [32]: dic = {'a':1, 'b':2, 'c':3, 'd':4}                                                                                            
    In [33]: dic['a']                                                                                                                      
    Out[33]: 1
    In [34]: dic['e']          # 不存在'e'这个key,所以直接访问会出现异常                                                                                                               
    ---------------------------------------------------------------------------
    KeyError                                  Traceback (most recent call last)
    <ipython-input-34-87d22c709971> in <module>
    ----> 1 dic['e']
    
    KeyError: 'e'
    In [35]: dic.get('a')     # key存在,则返回对应的值                                                                                                                
    Out[35]: 1
    In [36]: dic.get('e')     # 不存在,默认会返回None,ipython优化了None的输出,所以这里无显示                                                                                                             
    In [37]: dic.get('e','not exist')     # 不存在时,由指定的default进行返回                                                                                                 
    Out[37]: 'not exist'
    In [38]: dic.setdefault('a', 'ok?')   # 设置a的值为ok?,a存在,所以返回a对应的值1                                                                                                 
    Out[38]: 1
    In [39]: dic.setdefault('e', 'ok?')   # 设置e的值为ok?,e不存在,所以设置并放回value(key不存在时等同于设置并访问了)                                                                                                 
    Out[39]: 'ok?'
    In [40]: dic                                                                                                                           
    Out[40]: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'}
    

    当然字典也可以被迭代访问,后面介绍

    2.3 字典的增删改

            由于字典可变、非线性、无序的特性,而且字典的key必须是可hash的对象,查找某个key也是直接hash(),然后找到对应的房间的,所以我们对它某个key的修改可以理解为是O(1)的操作,效率很高,主要有以下几种方法。

    • d[key] = value: 将key对应的值修改为value,key不存在添加新的key:value对。
    • dic.update([other]) --> None: 使用另一个字典的k,v对更新本字典,key不存在时添加,存在时则覆盖,所以不会返回新的字典,属于原地修改。
    • dic.pop(key[, default]): key存在,移除它,并返回它的value,key不存在返回指定的default,如果default未指定,那么会返回KeyError异常。
    • dic.popitem(): 移除并返回一个任意的键值对,字典为empty时,抛出KeyError异常。
    • dic.clear(): 清空字典。
    • del dic['a']: 通用的删除变量方法。
    In [41]: dic                                                                                                                           
    Out[41]: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'}
    
    In [42]: dic['a'] = 1000                                                                                                               
    In [43]: dic                                                                                                                           
    Out[43]: {'a': 1000, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'}
    
    In [44]: dic2 = {'a':200,'f':50}                                                                                                       
    In [45]: dic.update(dic2)                                                                                                              
    In [46]: dic                                                                                                                           
    Out[46]: {'a': 200, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?', 'f': 50}
    
    In [48]: dic.pop('a')             # 弹出一个key'a',key存在返回key对应的value                                                                                                   
    Out[48]: 200
    
    In [49]: dic.pop('g')              # 弹出一个key'g',key不存在,又没有指定default,则会报KeyError异常                                                                                                        
    ---------------------------------------------------------------------------
    KeyError                                  Traceback (most recent call last)
    <ipython-input-49-311c3ba80251> in <module>
    ----> 1 dic.pop('g')
    
    KeyError: 'g'
    
    In [50]: dic.pop('g','not exist')       # 指定了default,当key不存在时,会返回指定的default值                                                                                               
    Out[50]: 'not exist'
    
    In [51]: dic.popitem()          # 弹出一个key:valyue键值对,返回对象是元组形式                                                                                                       
    Out[51]: ('d', 4)
    In [52]: dic                                                                                                                           
    Out[52]: {'b': 2, 'c': 3, 'e': 'ok?', 'f': 50}
    
    In [53]: del dic['e']                                                                                                                  
    In [54]: dic                                                                                                                           
    Out[54]: {'b': 2, 'c': 3, 'f': 50}
    
    In [55]: dic.clear()                                                                                                                   
    In [56]: dic                                                                                                                           
    Out[56]: {}
    

    当我们以字典的某个对象比如keys,values,items等为条件对字典进行遍历时,我们不能在遍历的同时删除字典的元素,字典在运行时不允许长度改变,但是在list中这种操作是可以的,但是会得到意想不到的结果,建议对容器进行遍历的同时不要修改它的长度。

    In [7]: s                                                                                           
    Out[7]: {'a': 1, 'b': 2, 'c': 4, 'd': 5, 'e': 7, 'j': 10}
    In [8]: len(s)                                                                                      
    Out[8]: 6
    In [10]: for i in range(6): 
        ...:     s.popitem() 
        ...:                                                                                            
    
    In [11]: s                                                                                          
    Out[11]: {}
    
    # 下面这种方式是错的,也是觉得不可以的。
    for i in s.keys():
        s.pop(i)
    

    3 字典遍历

            在Python中,我们所说的基本数据结构:字符串、元组、列表,集合,包括字典,都可以认为是一个容器箱子,只要是容器,我们就可以进行遍历(是否有序和是否可以遍历没有必然关系,只不过有序的话是顺序拿出,而无序则是随机拿出),我们可以使用多种方式对字典进行迭代遍历,但是有些地方和其他类型不同。

    3.1 遍历字典的key

            dic.keys(): --> dict_keys --> 返回字典dic的所有key组成的一个dict_keys视图集合(类set结构,不会生成新的内存空间)。

    In [64]: dic = {'a':1, 'b':2, 'c':3, 'd':4}                                                                                            
    
    In [65]: for key in dic: 
        ...:     print(key)                                                                                                                      
    a
    d
    c
    b
    
    In [66]: for key in dic.keys(): 
        ...:     print(key)                                                                                                                            
    a
    d
    c
    b
    
    In [67]: dic.keys()                                                                                                                    
    Out[67]: dict_keys(['a', 'd', 'c', 'b'])
    

    迭代字典就是在迭代字典的key,所以直接迭代字典和使用字典的keys()方法返回一个keys的视图然后再迭代,是一样的效果。

    3.2 遍历字典的value

            dic.values(): --> dict_values --> 返回字典dic的所有values组成的一个dict_values视图集合(类set结构,不会生成新的内存空间)。

    In [69]: for i in dic: 
        ...:     print(dic[i])                                                                                                                           
    1
    4
    3
    2
    
    In [70]: for i in dic.values(): 
        ...:     print(i)                                                                                                                           
    1
    4
    3
    2
    
    In [71]: dic.values()                                                                                                                  
    Out[71]: dict_values([1, 4, 3, 2])
    

    可以首先遍历字典的key,然后再通过key来访问对应的value,也可以通过values()直接访问values。

    3.3 变量字典的键值对

            dic.items(): --> dict_items --> 返回字典dic的所有的key和value(每个key和value的键值对由元组表示)组成的一个dict_items视图集合(类set结构,不会生成新的内存空间)。

    In [75]: for i in dic.items(): 
        ...:     print(i) 
        ...:                                                                                                                               
    ('a', 1)
    ('d', 4)
    ('c', 3)
    ('b', 2)
    
    In [77]: for key,value in dic.items(): 
        ...:     print('key:{} value:{}'.format(key,value)) 
        ...:                                                                                                                               
    key:a value:1
    key:d value:4
    key:c value:3
    key:b value:2
    
    In [78]: 
    

    由于返回的每个键值对为元组格式,那么利用我们前面学的封装与结构,可以很方便的获取key和它对应的value

    3.4 字典遍历小结

            在Python3中,keys、values、items方法返回一个类似一个生成器的可迭代对象,不会把函数的返回结果复制到内存空间中。

    • Dictionary view对象,可以使用len()、iter()、in
      操作
    • 字典的entry的动态视图,字典变化,视图将反映出这些变化
    • keys返回一个类似set的对象,也可以看作是一个set集合,如果values可hash的话,那么items也可以看作是类set对象
              Python 2中,keys、values、items方法会返回一个新的列表,占据新的内存空间,所以Python 2建议使用iterkeys、itervalues、iteritems,返回一个迭代器,而不是返回一个copy
    [11:20:32 python@centos7 ~]$python
    Python 2.7.5 (default, Oct 30 2018, 23:45:53) 
    [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> s = {'a':1,'b':2}
    >>> s.keys()    # 直接生成一个keys的列表
    ['a', 'b']
    >>> s.iterkeys()   # 对象,迭代可以获取数据
    <dictionary-keyiterator object at 0x7f271c5fa520>
    >>> 
    
    

    4 defaultdict默认值字典

            defaultdit object是dict的子类,我们称它为默认值字典,即在创建字典时给所有的value指定一个默认值,它存放在collections模块中,使用前需要先进行导入。为什么有默认值字典这种类型呢?那么请看如下代码:

    dic = {}
    for i in 'abacdabeddfef':
        if i not in dic:     # 这句其实也可以优化为 dic[i] = dic.get(i, 0) + 1
            dic[i] = 0
        dic[i] += 1
    print(dic)
    

            我们在计算一个字符串或者一个列表中的元素重复的次数时,通常会用到字典对齐进行计数,如果元素不存在字典中,那么就需要初始化元素,当我们使用默认值字典时,就可以优化的更简洁。

    from collections import defaultdict
    dic = defaultdict(int)   # defaultdict(lambda :0)  这种方法也可以设置默认为0
    for i in 'abacdabeddfef':
        dic[i] += 1    # 默认是int型,可以直接加减
    print(dic)
    

    5 OrdereDict有序字典

            Ordered dictionaries像一个有序字典,但是它记住的是插入元素的顺序。当我们迭代有序字典时,它会按照这些键值对插入的顺序返回。它同样存在于collections模块中,需要使用是请首先导入。

    In [1]: from collections import OrderedDict                                                                                                                                                                                          
    In [2]: dic = OrderedDict()                                                                                                                                                                                                          
    In [5]: dic = dic.fromkeys('abc',1)                                                                                                                                                                                                  
    In [6]: dic                                                                                                                                                                                                                          
    Out[6]: OrderedDict([('a', 1), ('b', 1), ('c', 1)])
    In [8]: for k,v in dic.items():     # 按照插入的顺序
       ...:     print(k,v) 
       ...:                                                                                                                                                                                                                              
    a 1
    b 1
    c 1
    In [10]: dic = dict([('a', 1), ('b', 1), ('c', 1)])                                                                                                                                                                                  
    
    In [11]: for k,v in dic.items():    # 无序的
        ...:     print(k,v) 
        ...:                                                                                                                                                                                                                             
    a 1
    c 1
    b 1
    
    In [12]:       
    

    注意:在3.6的版本的python在python/ipython解释器中,直接迭代或者打印时,是有序的(OrderedDict),但是在3.5版本以前都是随机的,千万不要以为字典是有序的!

  • 相关阅读:
    bzoj 2084: Antisymmetry 回文自动机
    bzoj 1819: 电子字典 Trie
    bzoj 1398: 寻找主人 AC自动机+最小表示法
    bzoj 4199: [Noi2015]品酒大会 后缀树
    bzoj 4044: Virus synthesis 回文自动机
    信用风险评分卡研究-第4章笔记
    信用风险评分卡研究-第3章笔记
    信用风险评分卡研究-第2章笔记
    信用风险评分卡研究-第1章笔记
    评分卡建模流程目录
  • 原文地址:https://www.cnblogs.com/dachenzi/p/10484291.html
Copyright © 2011-2022 走看看