如何在Python中初始化空列表字典?

Mar*_*rch 77 python dictionary list

我尝试以编程方式创建列表字典是不允许我单独地解决字典键.每当我创建列表字典并尝试附加到一个键时,所有这些都会更新.这是一个非常简单的测试用例:

data = {}
data = data.fromkeys(range(2),[])
data[1].append('hello')
print data
Run Code Online (Sandbox Code Playgroud)

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

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

这是有效的

data = {0:[],1:[]}
data[1].append('hello')
print data
Run Code Online (Sandbox Code Playgroud)

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

为什么fromkeys方法不能按预期工作?

Sve*_*ach 93

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

在Python 2.7或更高版本中,您可以使用dicitonary理解:

data = {k: [] for k in range(2)}
Run Code Online (Sandbox Code Playgroud)

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

data = dict((k, []) for k in range(2))
Run Code Online (Sandbox Code Playgroud)

  • 好吧,这是相当不直观的行为,您知道为什么所有键都使用同一个对象吗? (3认同)
  • @Bar因为函数在Python语言的语义中没有其他功能.传入单个对象以用作所有键的值,以便将单个对象用于所有键.对于`fromkeys()`方法来说,接受一个工厂函数会更好,所以我们可以将`list`作为一个函数传入,并且对于每个创建的密钥都会调用一次该函数,但这不是实际的API `dict.fromkeys()`. (2认同)
  • 这一点都不直观。我花了一个小时才找到。谢谢 (2认同)

Mar*_*ers 69

请改用defaultdict:

from collections import defaultdict
data = defaultdict(list)
data[1].append('hello')
Run Code Online (Sandbox Code Playgroud)

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

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

alist = [1]
data = dict.fromkeys(range(2), alist)
alist.append(2)
print data
Run Code Online (Sandbox Code Playgroud)

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

  • 在我的情况下,我需要事先初始化所有键,以便程序逻辑的其余部分可以按预期工作,但这将是一个很好的解决方案.谢谢. (2认同)

cob*_*bie 7

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

d = {k : v for k in blah blah blah}
Run Code Online (Sandbox Code Playgroud)