字典是一种key-value结构, redis、mencached、json都是这种结构
这里需要值得注意的是:
集合的定义里面是:s = set() 或者直接 s = {1, 2, 3}而不存在空的{}来定义的。另外还有几种定义的方法;
#第一种:直接用dict()来定义 >>> d = dict( ... name='kidult', ... title='smart', ... age=21, ... ) >>> d {'name': 'kidult', 'title': 'smart', 'age': 21} #第二种:用{} >>> d = { ... 'name':'kidult', ... 'title':'smart', ... 'age':21, ... } >>> d {'name': 'kidult', 'title': 'smart', 'age': 21} >>> type(d) <class 'dict'>第三种有两点要求:
可迭代对象的元素必须是一个二元组二元组的第0个元素是字典的key,第一个元素为字典的value >>> d = dict([('a', 1), ('b', 2)]) >>> d {'a': 1, 'b': 2}还有一种初始化的方式,传入的可迭代对象元素为key,值为abc
>>> d = dict.fromkeys(range(5),'abc') >>> d {0: 'abc', 1: 'abc', 2: 'abc', 3: 'abc', 4: 'abc'} #若第二个参数不写,则值为None >>> d = dict.fromkeys(range(5)) >>> d {0: None, 1: None, 2: None, 3: None, 4: None}可以直接使用key作为下标,对某个不存在的下标赋值,会增加key-value对
>>> d {0: 'abc', 1: 'abc', 2: 'abc', 3: 'abc', 4: 'abc'} >>> d['a'] = 'kidult学python' >>> d {0: 'abc', 1: 'abc', 2: 'abc', 3: 'abc', 4: 'abc', 'a': 'kidult学python'}通过update方法可以同时更新多个键值对,甚至将一个新的字典更新到另一个字典里:
>>> d.update([('c', 3),('p', 0)]) >>> d {0: 'abc', 1: 'abc', 2: 'abc', 3: 'abc', 4: 'abc', 'a': 'kidult学python', 'c': 3, 'p': 0}update传入参数和dict一样,可以接受一个可迭代对象
如下操作也可:
>>> d = {} >>> d.update({'age':21,'name':'kidult'}) >>> d {'age': 21, 'name': 'kidult'} #若存在相同的key就会修改字典,所有update通常用于合并字典 >>> d {'age': 21, 'name': 'kidult'} >>> d.update({'age':20, 'love':'python'}) >>> d {'age': 20, 'name': 'kidult', 'love': 'python'}当key存在,对下标赋值的时候,会修改这个key对于的value。
看下pop的签名,和list不一样,dict.pop需要传入一个key,这个key是字典中的键,他会返回这个key的value。 在key不存在的情况下:如果传入了第二个参数d,那么就返回给你d,这里的d就是默认值default,否则抛出KeyError异常。
>>> d.pop('age') 18 >>> d {'name': 'kidult', 'love': 'python'} #key不存在时: #1.定义了default >>> d.pop('age', 'default') 'default' #2.没有default,会抛出异常KeyError >>> d.pop('age') Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'age' dict.popitem >>> help(d.popitem) Help on built-in function popitem: popitem(...) method of builtins.dict instance D.popitem() -> (k, v), remove and return some (key, value) pair as a 2-tuple; but raise KeyError if D is empty.看签名解释是随机返回一个kv对的二元组。如果字典为空,就会返回KeyError
>>> d.popitem() ('love', 'python') >>> d.popitem() ('name', 'kidult') >>> d.popitem() Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'popitem(): dictionary is empty' dict.clear 清空一个字典 >>> d {'name': 'kidult', 'title': 'smart', 'age': 21} >>> d.clear() >>> d {}当一个字典已经为空时,clear()方法不会有任何反应,也不会抛出异常。
del >>> d {'name': 'kidult', 'title': 'smart', 'age': 21} >>> del d['title'] >>> d {'name': 'kidult', 'age': 21}del语句删除一个键的引用,相当于dict.pop('title'),所有一般使用pop。 修改键值需要先删除再添加的方法。
当key不存在时会抛出KeyError。
get()方法访问不存在的key的时候返回None,事实上,返回的是一个默认值,只不过这个默认值是None:
>>> d.get('age') 21 >>> d {'name': 'kidult', 'age': 21, 0: 'abc', 1: 'abc'} >>> d.get(2) >>> d.get(2,'没有') '没有'd.setdefault()方法可以用来初始化一个有默认值的字典:
>>> help(d.setdefault) Help on built-in function setdefault: setdefault(key, default=None, /) method of builtins.dict instance Insert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default.效果如下:
>>> d {'name': 'kidult', 'age': 21, 0: 'abc', 1: 'abc'} >>> d.setdefault(2,'default') 'default' #当字典里没有设置的默认key时,出现 >>> d {'name': 'kidult', 'age': 21, 0: 'abc', 1: 'abc', 2: 'default'} >>> d[2] = 'haha' >>> d {'name': 'kidult', 'age': 21, 0: 'abc', 1: 'abc', 2: 'haha'} >>> d.setdefault(2,'default') 'haha' #当字典里有设置的默认key时,不出现 >>> d {'name': 'kidult', 'age': 21, 0: 'abc', 1: 'abc', 2: 'haha'}其实是先调用get(k,default),然后赋值,然后返回该值,如下:
def setdefault(d, k, default): value = d.get(k,default) d[k] = value return value访问单个元素,要么用下标,要么用get方法
字典的遍历 字典的元素都是成对出现的 >>> for x in d: ... print(x) ... name age 0 1 2 >>> d {'name': 'kidult', 'age': 21, 0: 'abc', 1: 'abc', 2: 'haha'}如上可知:直接用for in遍历字典,遍历的是字典的key 可以直接使用d.values()的方式获取到字典的值
>>> d.values() dict_values(['kidult', 21, 'abc', 'abc', 'haha'])values会返回一个可迭代对象,元素是字典的所有value
>>> for v in d.values(): ... print(v) ... kidult 21 abc abc haha而d.items()可以返回元素为字典的所有kv对的可迭代对象:
>>> for k, v in d.items(): ... print(k,': ',v) ... name : kidult age : 21 0 : abc 1 : abc 2 : haha看下defaultdict的解释
>>> help(defaultdict) Help on class defaultdict in module collections: class defaultdict(builtins.dict) | defaultdict(default_factory[, ...]) --> dict with default factory | | The default factory is called without arguments to produce | a new value when a key is not present, in __getitem__ only. | A defaultdict compares equal to a dict with the same items. | All remaining arguments are treated the same as if they were | passed to the dict constructor, including keyword arguments.defaultdict初始化的时候,需要传入一个函数,这个函数也叫工厂函数 当我们使用下标访问一个key的时候,如果这个key不存在,defaultdict会自动调用初始化时传入的函数,生成一个对象作为这个key的value 如下:
#普通版本 d = {} for k in range(3): for v in range(3): if k not in d.keys(): d[k] = [] d[k].append(v) >>> d {0: [0, 1, 2], 1: [0, 1, 2], 2: [0, 1, 2]} #使用defaultdict >>> d = defaultdict(list) >>> for k in range(3): ... for v in range(3): ... d[k].append(v) ... >>> d defaultdict(<class 'list'>, {0: [0, 1, 2], 1: [0, 1, 2], 2: [0, 1, 2]})使用defaultdict就不再需要去判断有没有值,因为没有值的时候,他会去找defaultdict初始化时候传入的list,那么初始化的时候就变成了一个空列表。
高阶函数 先定义一个工厂函数f,当我们将这个工厂函数传入defaultdict的时候,若值不存在,就会生成一个默认值,这个值就是‘a’,是工厂函数f返回的: >>> def f(): ... print('f is called') ... return 'a' ... >>> d = defaultdict(f) #这里因为xxx这个key并不存在,所有默认调用f将a赋值。 >>> d['xxx'] f is called 'a' >>> d defaultdict(<function f at 0x00000201116FDA68>, {'xxx': 'a'})若是继续对字典d查询一次不存在的yyy这个键,会发现如下情况:
>>> d['yyy'] f is called 'a' >>> d defaultdict(<function f at 0x00000201116FDA68>, {'xxx': 'a', 'yyy': 'a'})如上,发现值均被添加,若此时查询已有的xxx键,f则不会被调用了。
>>> d['xxx'] 'a' 有序字典 >>> from collections import OrderedDict >>> d = OrderedDict() >>> d[0] = 3 >>> d[3] = 4 >>> d[1] = 5 >>> d OrderedDict([(0, 3), (3, 4), (1, 5)]) >>> for k, v in d.items(): ... print(k, ': ', v) ... 0 : 3 3 : 4 1 : 5此时字典变得有序输出了。然而事实上python3.6之后字典都是有序的了。 Q:什么时候需要有序字典? A:即是kv对,又需要顺序时。