Python学习笔记--字典及常用操作

前言

字典是一种key-value结构,
redis、mencached、json都是这种结构

定义

>>> d = {}
>>> type(d)
<class 'dict'>
>>> d
{}

这里需要值得注意的是:

集合的定义里面是: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'}

修改

>>> d
{'age': 20, 'name': 'kidult', 'love': 'python'}
>>> d['age'] = 18
>>> d
{'age': 18, 'name': 'kidult', 'love': 'python'}

当key存在,对下标赋值的时候,会修改这个key对于的value。

删除

  • dict.pop
>>> help(d.pop)
Help on built-in function pop:

pop(...) method of builtins.dict instance
    D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
    If key is not found, d is returned if given, otherwise KeyError is raised

看下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。
修改键值需要先删除再添加的方法。

访问

  • 单个元素的访问
>>> d.update(d.fromkeys(range(2),'abc'))
>>> d
{'name': 'kidult', 'age': 21, 0: 'abc', 1: 'abc'}
>>> d[0]
'abc'

当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

字典的限制

  • 字典的key不能重复
  • 字典的key需要可hash
>>> d[[1, 2, 3]] = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
  • 字典也不能做字典的key

字典的变体

  • 默认字典
>>> from collections import defaultdict
>>> d1 = {}
>>> d2 = defaultdict()
>>> d1
{}
>>> d2
defaultdict(None, {})

看下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对,又需要顺序时。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值