流程python学习笔记:第三章(1)

xiaoxiao2021-02-28  8

字典: 字典在python也是一种经常使用的数据结构。在数据的存储很方便。首先来看下字典中对于键值的处理。在字典index中,只有a:1这一个键值对。如果去取b的键值,则会抛出异常报错。提示找不到键值 index={'a':1} print index['b'] E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py Traceback (most recent call last):   File "E:/py_prj/fluent_python/chapter3.py", line 9, in <module>     get_item()   File "E:/py_prj/fluent_python/chapter3.py", line 5, in get_item     print index['b'] KeyError: 'b' 在这种键值找不到的情况下会直接抛出异常,导致程序中断。这是可以用get的方法来设置当找不到对应的键值时候的默认值。 index={'a':1} print index.get('b',[]) 此是虽然也找不到键值,但是不会抛出异常,而是直接返回一个空的列表。这比刚才方便多了 再把需求提升一下,当找不到键值的时候,不光是返回一个指定值,还需要对这个列表对这个缺失的键值进行更新。需要如何操作呢。代码更新如下。 index={'a':1} missing=index.get('b',])  #第一步没找到b,则返回一个空列表给missing missing.append(2)    #missing列表添加一个新元素 index['b']=missing   #在字典中更新b的值 print index E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py {'a': 1, 'b': [2]}   上面的例子总共用了三步来完成字典缺失字段的更新。有没有一种更简便的方法呢。Dict.setdefault可以用一行代码来解决。代码如下。 index={'a':1} index.setdefault('b',[]).append(2) print index E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py {'a': 1, 'b': [2]} 在代码中,查找,更新用一行代码完成,相比前面的例子,对于字典只进行了一次查询。   需求再升级一下,有没有一种字典类型,当找不到对应的键值的时候自动更新数值呢。这里就要用到defaultdict index=collections.defaultdict(list)  #这里用defaultdict生成一个字典,并且用list构造方法作为default_factory来创建一个defaultdict index['a'].append(1) print index E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py defaultdict(<type 'list'>, {'a': [1]}) 如果不设置这个default_factory.会是什么结果。 index=collections.defaultdict() E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py Traceback (most recent call last):   File "E:/py_prj/fluent_python/chapter3.py", line 16, in <module>     default_try()   File "E:/py_prj/fluent_python/chapter3.py", line 10, in default_try     index['a'].append(1) KeyError: 'a' 这里会抛出异常。证明当找不到键值的时候,会调用defalut_factory创建一个默认值。在Python所有的数据都是类。对于字典也是如此,在进行index[a]的时候其实是调用的__getitem__。那么在找不到键值的时候,其实是调用的__missing__这个方法。 我们首先来看下代码中对于__missing__的定义,注释中写道__missing__是被__getitem__所调用的。当default_factory为空的时候,则抛出异常。否则则用default_facotry来更新。 def __missing__(self, key): # real signature unknown; restored from __doc__     """     __missing__(key) # Called by __getitem__ for missing key; pseudo-code:       if self.default_factory is None: raise KeyError((key,))       self[key] = value = self.default_factory()       return value     """ 我们首先来看下书中的代码: class StrkeyDict0(dict):     def __missing__(self,key):         if isinstance(key,str):             raise KeyError(key)         return self[str(key)]     def get(self,key,default=None):         try:             return self[key]         except KeyError:             return default     def __contains__(self, key):         return key in self.keys() or str(key) in self.keys() d=StrkeyDict0([('2','two'),('4','four')]) print d[1] 运行结果如下:抛出了异常。 E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py Traceback (most recent call last):   File "E:/py_prj/fluent_python/chapter3.py", line 30, in <module>     print d[1]   File "E:/py_prj/fluent_python/chapter3.py", line 17, in __missing__     return self[str(key)]   File "E:/py_prj/fluent_python/chapter3.py", line 16, in __missing__     raise KeyError(key) KeyError: '1' 断点来看下这个程序的运行:

第一步:key是整数1,判断不是字符串,则执行return self[str(key)]。首先将key转换成字符串,然后在字典中取这个值

第二步: Key 变成了字符,此时判断属于字符,抛出 KeyError 

我们将__missing__改写下。当找不到键值的时候。直接进行赋值。 def __missing__(self,key):     if isinstance(key,str):         self[key]='three'     return self[str(key) 那么运行结果就是 E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py three   我们再回到最开始的代码,看下get方法的调用 d=StrkeyDict0([('2','two'),('4','four')]) print d.get(3,[]) E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py [] 单步调试下: 第一步: Key值为3,找不到对应的键值,下一步跳到__missing__方法处理

第二步__missing__中首先转换成字符查找一次

第三步,字符3还是找不到,则跑出KeyError的异常

第四步,接收到异常,于是返回defalut值,也就是调用的时候d.get(3,[]) 的空列表。

继续更新下代码:就和之前用dict来设置缺省的键值一 样。 d=StrkeyDict0([('2','two'),('4','four')]) ret=d.get(3,[]) ret.append('three') d[3]=ret print d[3] E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py ['three'] 此时print d[3]就是[‘three’]

转载请注明原文地址: https://www.6miu.com/read-1150384.html

最新回复(0)