Python进阶08_字典推导以及处理字典中不存在的键

字典推导(diccomp)

可以从任何以键值对作为元素的可迭代对象中构建出字典。
一般可以将元组的列表利用推导变成字典的数据类型。coding如下
country_code = {country:code for code,country in dial_codes}

  • 推导的时候利用{}
  • 在for之前要定义好格式:谁是键,谁是值
  • 在for中也要将对应的参数放进去:code,country
dial_codes = [ (86, 'China'), 
            (91, 'India'), 
            (1, 'United States'), 
        	(62, 'Indonesia'), 
        	(55, 'Brazil'), 
         	(92, 'Pakistan'), 
        	(880, 'Bangladesh'), 
         	(234, 'Nigeria'), 
         	(7, 'Russia'), 
        	(81, 'Japan') ]

print(dial_codes)
# 利用推导来获取数据
country_code = {country:code for code, country in dial_codes}
print(country_code)
# 这里
country_code2 = {code:country.upper() for code,country in dial_codes}

print(country_code2)
[(86, 'China'), (91, 'India'), (1, 'United States'), (62, 'Indonesia'), (55, 'Brazil'), (92, 'Pakistan'), (880, 'Bangladesh'), (234, 'Nigeria'), (7, 'Russia'), (81, 'Japan')]
{'Brazil': 55, 'Bangladesh': 880, 'Russia': 7, 'China': 86, 'Nigeria': 234, 'Japan': 81, 'Indonesia': 62, 'United States': 1, 'India': 91, 'Pakistan': 92}
{880: 'BANGLADESH', 1: 'UNITED STATES', 86: 'CHINA', 55: 'BRAZIL', 7: 'RUSSIA', 234: 'NIGERIA', 91: 'INDIA', 92: 'PAKISTAN', 62: 'INDONESIA', 81: 'JAPAN'}

常见的映射方法

常见的映射方法列表

dict、defaultdict 和 OrderedDict 的常见方法,后面两个数据类型是 dict 的变种,如下:

常见的映射方法列表

常见的映射方法列表

映射类型构造方法常见的逻辑

例如 update 方法:

  • 函数首先检查 m是否有 keys 方法,如果有,那么 update 函数就把它当作映射对象来处理。
  • 否则,函数会退一步,转而把 m 当作包含了键值对 (key, value) 元素的迭代器。

神奇的setdefault

一般处理字典中找不到键的方法:

  • 直接用d[k]的时候,python 会直接报错,抛出异常。
  • d.get(k,default),会返回一个值:default,这个值可以自己修改

这里推荐的方法:

  • 使用setdefault,就可以节省不少次键查询
    为什么可以减少次数,因为setdefault,只需要一次查找,就可以完成新的字典的添加,不需要重复判断occurrences = index.get(word,[]) 或者if key not in my_dict
# 使用d.get(k,default)处理不存在的键

def showWord(filePath):
    import sys
    import re
    
    # 正则表达式
    WORD_RE = re.compile(r'\w+')

    index = {}
    with open(filePath,encoding='utf-8') as fp:
        for line_no,line in enumerate(fp,1):
            for match in WORD_RE.finditer(line):
                word = match.group()
                column_no = match.start() + 1
                location = (line_no,column_no)
                # 查找key否存在,不存在则返回一个空列表[]
                occurrences = index.get(word,[])
                # 将找打的新的数据放到列表的后面
                occurrences.append(location)
                # 再把列表放到对应的字典中
                index[word] = occurrences
        # 利用关键字key=参数来排序,
        # 意思是在排序前,先将key变成大写字母
        for word in sorted(index,key=str.upper):
            print(word,index[word])
                
showWord("waliai.txt")
about [(2, 36)]
accounts [(1, 29), (2, 92), (3, 36)]
AI [(1, 10), (2, 46), (3, 24)]
and [(2, 61)]
are [(2, 32), (4, 4)]
can [(2, 5)]
find [(2, 9)]
follow [(3, 8)]
for [(4, 16)]
in [(1, 38), (2, 76)]
information [(2, 49)]
is [(1, 13)]
offical [(2, 84)]
official [(1, 20), (3, 27)]
papers [(2, 19)]
please [(3, 1)]
some [(2, 14)]
techenical [(2, 65)]
The [(1, 1)]
the [(1, 16), (2, 42), (3, 15)]
this [(2, 79)]
waiting [(4, 8)]
Wali [(1, 5), (3, 19)]
We [(4, 1)]
Wechat [(1, 41)]
which [(2, 26)]
You [(2, 1)]
you [(4, 20)]
# 使用setdefault处理不存在的键

def showWordBysetdefault(filePath):
    import sys
    import re
    
    # 正则表达式
    WORD_RE = re.compile(r'\w+')

    index = {}
    with open(filePath,encoding='utf-8') as fp:
        for line_no,line in enumerate(fp,1):
            for match in WORD_RE.finditer(line):
                word = match.group()
                column_no = match.start() + 1
                location = (line_no,column_no)
                #使用setdefault 函数来出来
                # 如果单词不存在,则把单词和空列表放进映射,返回一个空列表
                index.setdefault(word,[]).append(location)
        # 利用关键字key=参数来排序,
        # 意思是在排序前,先将key变成大写字母
        for word in sorted(index,key=str.upper):
            print(word,index[word])
showWordBysetdefault("waliai.txt")
about [(2, 36)]
accounts [(1, 29), (2, 92), (3, 36)]
AI [(1, 10), (2, 46), (3, 24)]
and [(2, 61)]
are [(2, 32), (4, 4)]
can [(2, 5)]
find [(2, 9)]
follow [(3, 8)]
for [(4, 16)]
in [(1, 38), (2, 76)]
information [(2, 49)]
is [(1, 13)]
offical [(2, 84)]
official [(1, 20), (3, 27)]
papers [(2, 19)]
please [(3, 1)]
some [(2, 14)]
techenical [(2, 65)]
The [(1, 1)]
the [(1, 16), (2, 42), (3, 15)]
this [(2, 79)]
waiting [(4, 8)]
Wali [(1, 5), (3, 19)]
We [(4, 1)]
Wechat [(1, 41)]
which [(2, 26)]
You [(2, 1)]
you [(4, 20)]

映射的弹性键查询

这里要处理一个问题是:有时候为了方便起见,就算某个键在映射里不存在,我们也希望在通过这个键读取值的时候能得到一个默认值。这里两个方法:

  • 使用defaultdict
  • 定义一个 dict 的子类,然后在子类中实现 missing 方法。

defaultdict:处理找不到的键的一个选择

defaultdict 为什么可以处理不存在的键

因为在定义defaultdict对象的时候会提供一个构造方法,该方法可以处理不存在的键,具体是通过__getitem__返回某种默认的值。这个值跟上面setdefault很像。

定义defaultdict字典

dd = defaultdict(list),如果dd中不存在 key,会如此处理:

  • 调用 list() 来建立一个新列表。
  • 把这个新列表作为值,‘new-key’ 作为它的键,放到 dd 中
  • 返回这个列表的引用
    这个就跟setdefault很像一样。
# 使用defaultdict处理不存在的键

def showWordBydefaultdict(filePath):
    import sys
    import re
    import collections
    
    # 正则表达式
    WORD_RE = re.compile(r'\w+')

    index = collections.defaultdict(list)
    with open(filePath,encoding='utf-8') as fp:
        for line_no,line in enumerate(fp,1):
            for match in WORD_RE.finditer(line):
                word = match.group()
                column_no = match.start() + 1
                location = (line_no,column_no)
                index[word].append(location)
        # 利用关键字key=参数来排序,
        # 意思是在排序前,先将key变成大写字母
        for word in sorted(index,key=str.upper):
            print(word,index[word])
showWordBydefaultdict("waliai.txt")
about [(2, 36)]
accounts [(1, 29), (2, 92), (3, 36)]
AI [(1, 10), (2, 46), (3, 24)]
and [(2, 61)]
are [(2, 32), (4, 4)]
can [(2, 5)]
find [(2, 9)]
follow [(3, 8)]
for [(4, 16)]
in [(1, 38), (2, 76)]
information [(2, 49)]
is [(1, 13)]
offical [(2, 84)]
official [(1, 20), (3, 27)]
papers [(2, 19)]
please [(3, 1)]
some [(2, 14)]
techenical [(2, 65)]
The [(1, 1)]
the [(1, 16), (2, 42), (3, 15)]
this [(2, 79)]
waiting [(4, 8)]
Wali [(1, 5), (3, 19)]
We [(4, 1)]
Wechat [(1, 41)]
which [(2, 26)]
You [(2, 1)]
you [(4, 20)]

missing:处理找不到的键的又一选择

从字面来理解就很容易理解,这个函数是用来处理miss掉键的。而且这里我们要知道的是:
所有的映射类型在处理找不到的键的时候,都会牵扯到 missing 方法

dict 基类并没有实现该方法,但是如果自己写的类继承dict,还是可以通过实现该方法来处理不存在键。
需要了解的是:__missing__方法只会被__getitem__调用,也就是d[k]这样的格式。

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','tow'),('4','four')])
print (d['2'])
print (d[4])
#print(d[3])
print(d.get(1,"test"))
tow
four
test

小结

  • 通过元组或者列表的格式来做字典推导,格式如下:country_code = {country:code for code,country in dial_codes}
  • 处理不存在键的查找或添加可以使用如下方法
    • 直接用d[k]的时候,python 会直接报错,抛出异常
    • d.get(k,default),会返回一个值:default,这个值可以自己修改
    • 使用setdefault,就可以节省不少次键查询index.setdefault(word,[]).append(location)
    • 利用特俗的字典类型:defaultdict字典index = collections.defaultdict(list)
    • 自定义字典类型,必须实现特俗函数__missing__

分享关于人工智能,机器学习,深度学习以及计算机视觉的好文章,同时自己对于这个领域学习心得笔记。想要一起深入学习人工智能的小伙伴一起结伴学习吧!扫码上车!

瓦力人工智能 - 扫码上车

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值