a = dict(one=1, two=2, three=3)
b = {'one': 1, 'two': 2, 'three': 3}
c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
d = dict([('two', 2), ('one', 1), ('three', 3)])
e = dict({'one': 1, 'two': 2, 'three': 3})
print(a==b==c==d==e)
DIAL_CODES = [
(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_CODES}
print(country_code)
code_country = {code: country.upper() for country, code in country_code.items() if code < 66}
print(code_country)
|
dict |
defaultdict |
OrederedDict |
|
---|---|---|---|---|
d.clear() |
√ |
√ |
√ |
移除所有元素 |
d.__contains__(k) |
√ |
√ |
√ |
检查k是否在d中(k是键) |
d.copy() |
√ |
√ |
√ |
浅复制 |
d.__copy__() |
|
√ |
|
用于支持copy.copy |
d.default_factory |
|
√ |
|
在 __missing__ 函数中被调用的函数,用以给未找到的元素这只值 |
d.__delitem__(k) |
√ |
√ |
√ |
del d[k] 移除键为k的元素 |
d.fromkeys(it, [initial]) |
√ |
√ |
√ |
将迭代器it里的元素设置为映射里的键,如果有initial参数,就把它作为这些键对应的值。(默认是None) |
d.get(k, [default]) |
√ |
√ |
√ |
返回键k对应的值,如果字典里没有键k,则返回None或者default |
d.__getitem__(k) |
√ |
√ |
√ |
让字典d能用d[k] 的形式返回键k对应的值 |
d.items() |
√ |
√ |
√ |
返回d里所有的键值对 |
d.__iter__() |
√ |
√ |
√ |
获取键的迭代器 |
d.keys() |
√ |
√ |
√ |
获取所有键 |
d.__len__() |
√ |
√ |
√ |
可以用len(d) 的形式得到字典里键值对的数量 |
d.__missing__(k) |
|
√ |
|
当 __getitem__ 找不到对应键的时候,这个方法会被调用 |
d.move_to_end(k, [last]) |
|
|
√ |
把键为k的元素移动到最靠前或者最靠后的位置(last的默认值是True) |
d.pop(k, [default]) |
√ |
√ |
√ |
返回键k所对应的的值,然后移除这个键值对。如果没有这个键,返回None或者default |
d.popitem() |
√ |
√ |
√ |
随机返回一个键值对并从字典里移除它 |
d.__reversed__() |
|
|
√ |
返回倒叙的键的迭代器 |
d.setdefault(k, [default]) |
√ |
√ |
√ |
若字典里有键k,则直接返回k所对应的值;若无,则让d[k]=default,然后返回default |
d.__setitem__(k, v) |
√ |
√ |
√ |
实现d[k]=v操作,把k对应的值设为v |
d.update(m, [**kargs]) |
√ |
√ |
√ |
m可以是映射或者键值对迭代器,用来更新d里对应的条目 |
d.values() |
√ |
√ |
√ |
返回字典里的所有值 |
"""创建一个从单词到其出现情况的映射"""
import sys
import re
WORD_RE = re.compile(r'\w+')
index = {}
with open("xx.txt", encoding='UTF-8') as fp:
# enumerate(sequence, [start=0]) sequence -- 一个序列、迭代器或其他支持迭代对象。start -- 下标起始位置。
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)
# 下面是一种不好的实现
occurrences = index.get(word, [])
occurrences.append(location)
index[word] = occurrences
# 上面三行等价于下面一行
# 获取单词的出现情况列表,如果单词不存在,把单词和一个空列表放进映射,然后返回这个空列表
# 这样就能在不进行第二次查找的情况下更新列表
index.setdefault(word, []).append(location)
# 以字母顺序打印出结果
for word in sorted(index, key=str.upper):
print(word, index[word])
在上述的两种实现中,二者的效果都是一样的,只不过前者至少要进行两侧键查询-如果键不存在则是三次,用setdefault只需要一次就可以完成整个操作。
方法一如下:
import sys
import re
import collections
WORD_RE = re.compile(r'\w+')
# 把list构造方法作为default_factory来创建一个defaultdict
index = collections.defaultdict(list)
with open(sys.argv[1], encoding='UTF-8') as fp:
# enumerate(sequence, [start=0]) sequence -- 一个序列、迭代器或其他支持迭代对象。start -- 下标起始位置。
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的记录,那么default_factory会被调用,为查询不到的键创造一个值。
# 这个值在这里是一个空列表,然后这个空列表会被赋值给index[word],继而被当做返回值返回
# 因此,append(location)操作总能成功
index[word].append(location)
# 以字母顺序打印出结果
for word in sorted(index, key=str.upper):
print(word, index[word])
在创建defaultdict对象的时候,我们需要给它配置一个为找不到键创建默认值的方法。具体而言,在实例化一个defaultdict的时候,需要给构造方法提供一个可调用对象,这个可调用对象会在__getitem__碰到找不到的键的时候被调用,让 __getitem__返回一个默认值。
比如在上面,我们在实例化defaultdict的时候,提供了list可调用对象,当 __getitem__找不到键的时候,会按一下步骤来走:
1.调用list()来创建一个新列表
2.把这个新列表作为值,找不到的那个键作为它的键,放入字典中
3.返回这个列表的引用
这个用来生成默认值的可调用对象存放在名为default_factory的实例属性中。如果在创建defaultdict的时候没有指定default_factory,查询不存在的键会触发KeyError。
方法二(__missing__)如下:
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:
# get方法把查找工作用self[key]的形式委托给__getitem__,这样在宣布查找失败之前
# 还能通过 __missing__ 再给某个键一个机会
return self[key]
except KeyError:
return default
def __contains__(self, key):
return key in self.keys() or str(key) in self.keys()
if __name__ == "__main__":
d = StrKeyDict0([('2', 'two'), ('4', 'four')])
print(d[2])
print(d['2'])
print(d.get('2'))
print(d.get(2))
print(d.get(1, '不存在'))
注意:__missing__方法只会被__getitem__调用(比如在表达式d[k]中)。像 k in dict.keys() 这种操作在Python3中是很快的,而且即便映射类型对象很庞大也没关系,因为dict.keys()返回的值是一个“视图”。视图就像一个集合,而且跟字典类似的是,在视图里查找一个元素的速度很快。
Collections.Counter 一个很有用的映射类型,这个类型会给键准备一个整数计数器。每次更新一个键的时候都会增加这个计数器。所以这个类型可以用来给可散列对象技术,或者是当做多重集来用——对重集合就是集合里的元素可以出现不止一次。
ct = collections.Counter(["Hello", "sss", "sss", "sss", "hello"])
print(ct)
从Python3.3开始,types模块引入了一个封装类名叫MappingProxyType。如果给这个类一个映射,它会返回一个只读的映射视图。虽然是个只读的视图,但是它是动态的,即如果原映射出现了改动,那么我们可以通过这个视图观察到,但是无法通过这个视图对原映射进行修改。
from types import MappingProxyType
d = {1: 'A'}
d_proxy = MappingProxyType(d)
print(d_proxy) # d中的内容可以通过d_proxy看到
# d_proxy[1] = 'X' # 但是通过d_proxy并不能做任何修改
print(d_proxy)
d[1] = 'X'
print(d_proxy) # d_proxy是动态的,即对d所做的任何修改都会反馈到它上面