发条都指向同一个列表

2024-04-20 10:25:07 发布

您现在位置:Python中文网/ 问答频道 /正文

这让我有点悲伤。。。

我从一个列表中创建了一本词典

l = ['a','b','c']
d = dict.fromkeys(l, [0,0]) # initializing dictionary with [0,0] as values

d['a'] is d['b'] # returns True

如何使字典的每个值都成为一个单独的列表?如果不遍历所有键并将它们设置为一个列表,这可能吗?我想修改一个列表而不更改所有其他列表。


Tags: true列表dictionary字典isaswithdict
3条回答

你可以使用听写理解:

>>> keys = ['a','b','c']
>>> value = [0, 0]
>>> {key: list(value) for key in keys}
    {'a': [0, 0], 'b': [0, 0], 'c': [0, 0]}

这个答案是为了解释这个行为给那些被他们试图用fromkeys()实例化一个dict的结果弄糊涂的人,这个dict中有一个可变的默认值。

考虑:

#Python 3.4.3 (default, Nov 17 2016, 01:08:31) 

# start by validating that different variables pointing to an
# empty mutable are indeed different references.
>>> l1 = []
>>> l2 = []
>>> id(l1)
140150323815176
>>> id(l2)
140150324024968

所以对l1的任何改变都不会影响l2,反之亦然。 到目前为止,这对于任何可变的,包括dict都是正确的。

# create a new dict from an iterable of keys
>>> dict1 = dict.fromkeys(['a', 'b', 'c'], [])
>>> dict1
{'c': [], 'b': [], 'a': []}

这可能是一个方便的功能。 在这里,我们给每个键分配一个默认值,这个值碰巧也是一个空列表。

# the dict has its own id.
>>> id(dict1)
140150327601160

# but look at the ids of the values.
>>> id(dict1['a'])
140150323816328
>>> id(dict1['b'])
140150323816328
>>> id(dict1['c'])
140150323816328

事实上,他们都在使用同一个ref! 改变一个就是改变所有人,因为他们实际上是同一个对象!

>>> dict1['a'].append('apples')
>>> dict1
{'c': ['apples'], 'b': ['apples'], 'a': ['apples']}
>>> id(dict1['a'])
>>> 140150323816328
>>> id(dict1['b'])
140150323816328
>>> id(dict1['c'])
140150323816328

对许多人来说,这不是他们想要的!

现在让我们尝试将列表的显式副本用作默认值。

>>> empty_list = []
>>> id(empty_list)
140150324169864

现在用empty_list的副本创建一个dict。

>>> dict2 = dict.fromkeys(['a', 'b', 'c'], empty_list[:])
>>> id(dict2)
140150323831432
>>> id(dict2['a'])
140150327184328
>>> id(dict2['b'])
140150327184328
>>> id(dict2['c'])
140150327184328
>>> dict2['a'].append('apples')
>>> dict2
{'c': ['apples'], 'b': ['apples'], 'a': ['apples']}

仍然没有快乐! 我听到有人喊,因为我用的是空单子!

>>> not_empty_list = [0]
>>> dict3 = dict.fromkeys(['a', 'b', 'c'], not_empty_list[:])
>>> dict3
{'c': [0], 'b': [0], 'a': [0]}
>>> dict3['a'].append('apples')
>>> dict3
{'c': [0, 'apples'], 'b': [0, 'apples'], 'a': [0, 'apples']}

fromkeys()的默认行为是将None赋给该值。

>>> dict4 = dict.fromkeys(['a', 'b', 'c'])
>>> dict4
{'c': None, 'b': None, 'a': None}
>>> id(dict4['a'])
9901984
>>> id(dict4['b'])
9901984
>>> id(dict4['c'])
9901984

实际上,所有的值都是相同的(而且是唯一的!)None。 现在,让我们通过dict以多种方式之一迭代并更改值。

>>> for k, _ in dict4.items():
...    dict4[k] = []

>>> dict4
{'c': [], 'b': [], 'a': []}

嗯。看起来和以前一样!

>>> id(dict4['a'])
140150318876488
>>> id(dict4['b'])
140150324122824
>>> id(dict4['c'])
140150294277576
>>> dict4['a'].append('apples')
>>> dict4
>>> {'c': [], 'b': [], 'a': ['apples']}

但它们确实是不同的,这就是预期的结果。

您可以使用:

l = ['a', 'b', 'c']
d = dict((k, [0, 0]) for k in l)

相关问题 更多 >