Python基础之字典的使用——Dictionary

1.字典的介绍与创建

映射类型是一种关联式的容器类型,它存储了对象与对象之间的映射关系。简而言之就是通过名称来访问其各个值的数据结构,这种数据结构称为映射(mapping)
字典是Python中唯一一个内置的映射类型,其中的值不按顺序排列,而是存储在键下。键可以是数、字符串或者元组。

Python中的字典由及其相应的组成,这种键-值对称为项(item)。每个键与值之间都用冒号:分割,项之间用逗号隔开,而整个字典放在**花括号{}**内。

d = {key1 : value1, key2 : value2 } #字典的形式表示
phonebook = {'Alice':'1234', 'Bob':'9102','Cat':'3258'}

注意:在字典(以及其他映射类型)中,键必须是独一无二的,而值无需如此。

2.字典的函数dict

可以用函数dict从其他映射(如其他字典)或键-值对序列创建字典。

>>> item = [('name','Alice'),('age',21)]
>>> d = dict(item)
>>> d
{'age': 21, 'name': 'Alice'}
>>> d['name']
'Alice'

还可以用关键字实参来调用这函数

>>> d = dict(name='Alice',age=21,id='12345')
>>> d
{'age': 21, 'id': '12345', 'name': 'Alice'}

如上图,也可以使用一个映射实参来调用它,这将创建一个包含指定映射中所有项的字典。特别的,若该映射也是字典,则我们可以使用字典方法copy

3.字典的基本操作

字典的基本操作在很多方面类似于序列。

方法描述
len(d)返回字典d包含的项(键-值对)数
d[k]返回与键k相关联的值
d[k] = v值v关联到键k
del [k]删除键k的项
k in d检查字典d是否包含键k的项

不同之处:
键的类型: 字典中的键可以是整数也可以是非整数。字典中的键可以是任何不可变的值,如浮点数、字符串或元组。
自动添加: 即使字典中原来没有键,也可以给它赋值,这将在字典中创建一个新项。然而,如果不适用append或其它方法,就不能给列表中原有的元素赋值。
成员资格表达式k in d(d是一个字典)查找的是键而不是值,而表达式v in l(l 是一个列表)查找的是值而不是索引。

4.字典方法
4.1 celar

删除所有的字典项,因此什么都不返回也可以说返回None

>>> x = {}
>>> y = x
>>> x['key'] = 'value'
>>> y
{'key': 'value'}
>>> x = {}
>>> y
{'key': 'value'}

如果用clear来进行清除,则y也是空的。

>>> x = {}
>>> y = x
>>> y
{}
>>> x['key'] = 'value'
>>> y
{'key': 'value'}
>>> x.clear()
>>> y
{}
4.2 copy

返回一个新字典,其包含的键-值对与原来的字典相同(这种为浅复制,因为值本身是原件,而非副本)

>>> x = {'username':'admin','machine':['foo','bar','baz']}
>>> y = x.copy()
>>> y['username'] = 'mlh'
>>> y['machine'].remove('bar')
>>> y
{'machine': ['foo', 'baz'], 'username': 'mlh'}
>>> x
{'machine': ['foo', 'baz'], 'username': 'admin'}

正如你所看见的,发生了一件很诡异的事情:

  • 当替换副本中的值的时,原件不受影响;
  • 然后,当修改副本中的值时(就地修改而不是替换),原件也发生了变化,因为原件指向的也是被修改的值。

为了避免上述的问题,可执行深复制,用到copy模块中的函数deepcopy

  • copy 浅拷贝,只拷贝父对象,不会拷贝对象的内部的子对象。(比深拷贝更加节省内存)
  • deepcopy 深拷贝,拷贝对象及其子对象
>>> from copy import deepcopy
>>> d = {'names':['Alice','Bob'], 'loca':'china'}
>>> a = d
>>> c = d.copy()
>>> dc = deepcopy(d)
>>> print(d == c )
True
>>> print(d == dc )
True
>>> print(dc is c)
False

看上去相同,但不是同一个对象。

此时改变d的值:

>>> d['local'] = 'England' #操作1
>>> d['names'].append('Cat') #操作2

再查看结果:

>>> d
{'local': 'England', 'names': ['Alice', 'Bob', 'Cat'], 'loca': 'china'}
>>> a
{'local': 'England', 'names': ['Alice', 'Bob', 'Cat'], 'loca': 'china'}
>>> c
{'names': ['Alice', 'Bob', 'Cat'], 'loca': 'china'}
>>> dc
{'names': ['Alice', 'Bob'], 'loca': 'china'}

发现,操作1和2均改变了d和其引用a,
但是c只受操作2的影响,dc不受影响。
因为c是a的浅拷贝,值拷贝了父对象,而d的子对象列表[‘Alice’, ‘Bob’]改变时c也会收到影响;但是dc是深拷贝。完全不受影响。


此时,可能有人还不明白,我的理解是:

  • 1.深复制,即将被复制对象完全再复制一遍作为独立的新个体单独存在。所以改变原有被复制对象不会对已经复制出来的新对象产生影响
  • 2.浅复制,并不会产生一个独立的新对象,而是给原有的数据块取一个新名字(新标签),他们都引用同一块内存,所以当一个标签被改变时,数据块就会发生改变。

类似于下面代码:

>>> a = [1,2,3]
>>> b = a         # b是a的引用
>>> a = [4,5,6]   # 当a重新引用到另一内存块时,b不会有影响,还是引用
>>> print(a)      # 原来内存块
[4, 5, 6]
>>> print(b)
[1, 2, 3]

>>> a = [1,2,3]
>>> b = a
>>> a[0],a[1],a[2] = 4,5,6  # 但是改变a中元素的值,b也会变
>>> print(a)
[4, 5, 6]
>>> print(b)
[4, 5, 6]

所以,可以把浅复制中对子对象只是创建一个引用。

4.3 fromkeys

创建一个新字典,其中包含指定的键,且每个键对应夫人值都是None

>>> dict.fromkeys(['name','age'])
{'name': None, 'age': None}
>>> dict.fromkeys(['name','age'],'(unknown)') #提供默认值
{'name': '(unknown)', 'age': '(unknown)'}
>>> dict.fromkeys(['name','age'],'myvalue')
{'name': 'myvalue', 'age': 'myvalue'}
4.4 get

如果试图访问字典中没有的元素,将引发错误。

>>> d = {}
>>> print(d['name'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'name'

但是,用get来访问不存在的键时,不会引发异常,而是返回None。而且可以指定值而不是None

>>> d = {}
>>> d.get('name')
>>> print(d.get('name'))
None
>>> print(d.get('name','error'))
error
4.5 items

返回一个包含所有字典项的列表,其中每个元素都为**(key,value)**的形式,字典项目在列表中排列顺序不确定。

>>> phonebook = {'Alice':'1234', 'Bob':'9102','Cat':'3258'}
>>> phonebook.items()
dict_items([('Alice', '1234'), ('Cat', '3258'), ('Bob', '9102')])

>>> book = phonebook.items() #列表操作
>>> len(book)
3
>>> ('Alice','1234') in book
True

返回值属于一种名为字典视图的特殊类型。视图的优点是不复制,始终是底层字典的动态反映,即使你修改了底层字典。

>>> phonebook['Alice'] = '2345'
>>> ('Alice','1234') in book
False
>>> phonebook['Alice'] = '1234'
>>> ('Alice','1234') in book
True
4.6 keys

返回一个字典视图,包含指定字典中的键。

>>> phonebook = {'Alice':'1234', 'Bob':'9102','Cat':'3258'}
>>> phonebook.keys()
dict_keys(['Alice', 'Cat', 'Bob'])
4.7 pop

获取与指定键相关的值,并将该键-值对从字典中删除。

>>> phonebook = {'Alice':'1234', 'Bob':'9102','Cat':'3258'}
>>> phonebook.pop('Alice')
'1234'
>>> phonebook
{'Cat': '3258', 'Bob': '9102'}
4.8 popitem

不用指定键值,随机弹出一个字典项,可用于快速逐个删除并处理所有字典项。

4.9 setdefault

用法类似于get,获得与指定键相关联的值。但是,会在不包含指定键值的时候,在字典中添加键值对。

>>> d = {}
>>> d.setdefault('name','myvalue')
'myvalue'
>>> d
{'name': 'myvalue'}
>>> d.setdefault('name','error')
'myvalue'
4.10 update

使用一个字典中的项来更新另一个字典。

>>> book = {'Alice':'1234', 'Bob':'9102','Cat':'3258'}
>>> person = {'Alice':'2345'}
>>> book.update(person)
>>> book
{'Alice': '2345', 'Cat': '3258', 'Bob': '9102'}
>>> new = {'Dog':'1998'}
>>> book.update(new)
>>> book
{'Dog': '1998', 'Alice': '2345', 'Cat': '3258', 'Bob': '9102'}

更新包含相同键值的项,添加没有的。

4.11 values

返回一个由字典中值组成的字典视图,与keys恰好互补,但是方法values可能返回的视图包含重复值。

>>> d = {1:1,2:2,3:3,4:1}
>>> d.keys()
dict_keys([1, 2, 3, 4])
>>> d.values()
dict_values([1, 2, 3, 1])
参考文献

1.Beginning Python From Novice to Professional Third Edition. Magnus Lie Hetland
2.Python标准英文文档

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值