使用 fromkeys 和可变对象创建字典.惊喜 [英] Dictionary creation with fromkeys and mutable objects. A surprise

查看:30
本文介绍了使用 fromkeys 和可变对象创建字典.惊喜的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Python 2.6 和 3.2 中遇到了让我感到惊讶的行为:

<预><代码>>>>xs = dict.fromkeys(range(2), [])>>>xs{0: [], 1: []}>>>xs[0].append(1)>>>xs{0: [1], 1: [1]}

然而,3.2 中的 dict 推导式表现出更礼貌的举止:

<预><代码>>>>xs = {i:[] for i in range(2)}>>>xs{0: [], 1: []}>>>xs[0].append(1)>>>xs{0: [1], 1: []}>>>

为什么 fromkeys 会这样?

解决方案

您的 Python 2.6 示例等效于以下内容,这可能有助于澄清:

<预><代码>>>>a = []>>>xs = dict.fromkeys(range(2), a)

结果字典中的每个条目都将引用同一个对象.正如您所见,通过每个 dict 条目都可以看到对该对象进行变异的效果,因为它是一个对象.

<预><代码>>>>xs[0] 是一个,而 xs[1] 是一个真的

使用字典推导,或者如果您被困在 Python 2.6 或更早版本并且您没有字典推导,您可以通过使用 dict() 和生成器来获得字典推导行为表达:

xs = dict((i, []) for i in range(2))

I came across this behavior that surprised me in Python 2.6 and 3.2:

>>> xs = dict.fromkeys(range(2), [])
>>> xs
{0: [], 1: []}
>>> xs[0].append(1)
>>> xs
{0: [1], 1: [1]}

However, dict comprehensions in 3.2 show a more polite demeanor:

>>> xs = {i:[] for i in range(2)}
>>> xs
{0: [], 1: []}
>>> xs[0].append(1)
>>> xs
{0: [1], 1: []}
>>> 

Why does fromkeys behave like that?

解决方案

Your Python 2.6 example is equivalent to the following, which may help to clarify:

>>> a = []
>>> xs = dict.fromkeys(range(2), a)

Each entry in the resulting dictionary will have a reference to the same object. The effects of mutating that object will be visible through every dict entry, as you've seen, because it's one object.

>>> xs[0] is a and xs[1] is a
True

Use a dict comprehension, or if you're stuck on Python 2.6 or older and you don't have dictionary comprehensions, you can get the dict comprehension behavior by using dict() with a generator expression:

xs = dict((i, []) for i in range(2))

这篇关于使用 fromkeys 和可变对象创建字典.惊喜的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆