龙空技术网

python 关于字典dict的fromkeys方法的巨坑

程序员牧童 130

前言:

此时小伙伴们对“pythonfromkeys”可能比较珍视,咱们都需要学习一些“pythonfromkeys”的相关知识。那么小编也在网上收集了一些有关“pythonfromkeys””的相关资讯,希望我们能喜欢,朋友们快快来学习一下吧!

python 关于字典dict的fromkeys方法的巨坑,真的只有踩过之后才知道

1. 踩坑重现(错误示范)

1.1 通过fromkeys初始化一个空的字典

1.2 修改某一按键下的值

2. 初始化字典的正确方法

本文试验的python版本为3.6.2,先来看下python3.6官方文档上对fromkeys的描述,极其简单:

看似简单方便,实则很坑!

在某些场景下,需要初始化一个字典,键是确定的,但是值是需要等待去填充或修改的,正好字典自带的fromkeys方法似乎刚好可以做到这个事情,并可以初始化所有键的值。

但是fromkeys有一个巨坑,真的只有踩过之后才知道,请耐心往下看

首先先看下这个坑是怎么产生以及如何坑人的。

1. 踩坑重现(错误示范)

1.1 通过fromkeys初始化一个空的字典

d = dict.fromkeys(['a', 'b', 'c'], {'score':0, 'type': []})print(d)

初始化字典如下:

{	'a': {'score': 0, 'type': []}, 	'b': {'score': 0, 'type': []}, 	'c': {'score': 0, 'type': []}}
1.2 修改某一键下的值
d['a']['score'] = 3d['b']['type'].append('type b')print(d)
{	'a': {'score': 3, 'type': ['type b']}, 	'b': {'score': 3, 'type': ['type b']}, 	'c': {'score': 3, 'type': ['type b']}}

发现没有!通过fromkeys创建的初始字典,当修改某一键下的值时,所有的值都会随之修改!

这是因为通过fromkeys创建初始字典时,所设定的默认值,是存储在同一块存储空间上的,相当于所有的值都是同一个值,类似于浅拷贝。

关于深浅拷贝,可以参考我的这篇文章,解释得应该很清楚了:

python变量的引用赋值及深浅拷贝

2. 初始化字典的正确方法

所以如想正确初始化一个字典,应该采用类似于列表推导式的方法,如下:

d = {key: {'score': 0, 'type': []} for key in ['a', 'b', 'c']}print(d)

可以看到创建的字典效果一样的

{	'a': {'score': 0, 'type': []}, 	'b': {'score': 0, 'type': []}, 	'c': {'score': 0, 'type': []}}

并且可以正常修改键值:

d['a']['score'] = 3d['b']['type'].append('type b')print(d)
{	'a': {'score': 3, 'type': []}, 	'b': {'score': 0, 'type': ['type b']}, 	'c': {'score': 0, 'type': []}}

goodbye!!!

标签: #pythonfromkeys