106

我以编程方式创建列表字典的尝试未能允许我单独处理字典键。每当我创建列表字典并尝试附加到一个键时,它们都会更新。这是一个非常简单的测试用例:

data = {}
data = data.fromkeys(range(2),[])
data[1].append('hello')
print data

实际结果:{0: ['hello'], 1: ['hello']}

预期结果:{0: [], 1: ['hello']}

这是有效的

data = {0:[],1:[]}
data[1].append('hello')
print data

实际和预期结果:{0: [], 1: ['hello']}

为什么该fromkeys方法没有按预期工作?

4

4 回答 4

130

[]作为第二个参数传递dict.fromkeys()给了一个相当无用的结果——字典中的所有值都是同一个列表对象。

在 Python 2.7 或更高版本中,您可以改用字典推导:

data = {k: [] for k in range(2)}

在早期版本的 Python 中,您可以使用

data = dict((k, []) for k in range(2))
于 2012-07-16T17:50:49.670 回答
104

改用defaultdict

from collections import defaultdict
data = defaultdict(list)
data[1].append('hello')

这样,您不必事先将要用于列表的所有键初始化。

您的示例中发生的是您使用了一个(可变)列表:

alist = [1]
data = dict.fromkeys(range(2), alist)
alist.append(2)
print data

会输出{0: [1, 2], 1: [1, 2]}.

于 2012-07-16T17:50:10.870 回答
9

您正在使用对单个列表的引用填充字典,因此当您更新它时,更新会反映在所有引用中。尝试使用字典理解。请参阅 在 Python 中创建具有列表理解的字典

d = {k : v for k in blah blah blah}
于 2012-07-16T17:50:42.740 回答
-3

你可以使用这个:

data[:1] = ['hello']
于 2017-06-15T17:44:47.520 回答