字典推导
构造字典
DIAL_COODES=[ # 一个承载成对数据的列表,可以直接用在字典的构造方法中
(86,'China'),
(91,'India'),
(1,'United States'),
(62,'Indonesia'),
(55,'Brazil'),
(92,'Pakistan'),
(880,'Bangladesh'),
(234,'Nigeria'),
(7,'Russia'),
(81,'Japan')
]
country_code={country:code for code ,country in DIAL_COODES} # 将配好对的数据左右换了下,国家名是键,区域码是值
country_code
{'China': 86,
'India': 91,
'United States': 1,
'Indonesia': 62,
'Brazil': 55,
'Pakistan': 92,
'Bangladesh': 880,
'Nigeria': 234,
'Russia': 7,
'Japan': 81}
{code :country.upper() for country,code in country_code.items() if code<66}
# 用区域码作为键,国家名称转换为大写,并且过滤调区域码大于或等于66的地区
{1: 'UNITED STATES', 62: 'INDONESIA', 55: 'BRAZIL', 7: 'RUSSIA'}
特殊方法__missing__
在__getitem__碰到找不到的键时,Python就会自动调用__missing__而不是抛出KeyError异常
基本类型dict没有定义这个方法,但是dict有这个方法。如果有一个类继承了dict,然后这个继承类提供了__missing__方法
class StrKeyDict0(dict): # StrKeyDick0继承了dict
def __missing__(self,str):
if isinstance(key,str): # 如果找到的键本身就是字符串,抛出KeyError异常
raise KeyError(key)
return self[str[key]] # 如果找到的键不是字符串,那就把它转换成字符串再查找
def get(self,key,default=None):
try:
return self[key]
# get方法把查找的工作用self[key]的形式委托给__getitem__,这样在宣布查找失败之前,还能通过__missing__再给某个键一个机会
except KeyError: # 如果抛出KeyError异常,那么说明__missing__也失败了,于是返回default
return default
def __contains__(self,key):
return key in self.keys() or str(key) in self.keys()
# 用传入的键查找,如果没找到再用str()方法把键转换成字符串再查找一遍
子类化UserDict
import collections
class StrKeyDict(collections.UserDict): # StrKeyDict是对UserDict的拓展
def __missing__(self,key): # __missing__和上面的一样
if isinstance(key,str):
raise KeyError(key)
return self[str(key)]
def __contains__(self,key): # __contains__则更简洁,这里可以放心所有已存储的键都是字符串。因此,只要在self.data上查询就好
return str(key) in self.data
def __setitem__(self,key,item): # __setitem__会将所有键都转换成字符串,把具体的实现委托给了self.data属性
self.data[str(key)]=item
不可变映射类型
from types import MappingProxyType
d={1:'A'}
d_proxy=MappingProxyType(d)
d_proxy
mappingproxy({1: 'A'})
d_proxy[1] # d中的内容可以通过d_proxy看到
'A'
d_proxy[2]='x' # 但是通过d_proxy并不能做任何修改
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_5844/3467132180.py in <module>
----> 1 d_proxy[2]='x'
TypeError: 'mappingproxy' object does not support item assignment
d[2]='B'
d_proxy # d_proxy是动态的,对d做的任何改动都会反馈到它上面去
mappingproxy({1: 'A', 2: 'B'})
d_proxy[2]
'B'