这让我有点悲痛...

我从列表中创建了一个字典

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

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


我该如何使...的每个值字典有单独的清单吗?是否可以在不迭代所有键并将它们设置为等于列表的情况下实现?我想修改一个列表而不更改其他列表。

评论

如何在Python中初始化空列表字典的可能重复项?

#1 楼

您可以使用dict理解:

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


评论


list(value)与value [:]是同一件事吗?

– Droogans
2014年4月20日在1:56

@Droogans:是的。我只是发现空切片符号很难看。

– Blender
2014年4月20日在2:51

value [:]并不那么丑陋(除非您与Alex Martelli有着相同的审美观:)),而且打字也更少。在最新版本的Python中,现在有一个list.copy方法。就性能而言,切片对于较小的列表(最多50或60个项目)最快,但是对于较大的列表,列表(值)实际上要快一些。 value.copy()的性能似乎与list(value)相似。对于大型列表,所有这三种技术都会显着降低:在我的32位旧机器上,大约32k,YMMV取决于您的CPU的字大小和缓存大小。

– PM 2环
18年7月14日在8:25

#2 楼

这个答案在这里向那些被试图在实例中初始化具有可变默认值的dictfromkeys()实例化结果的人解释这种行为。

考虑:

#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


,因此对dict的任何更改都不会影响l1,反之亦然。
到目前为止,对于任何可变的情况(包括l2)都是如此。

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


这可以是一个方便的功能。
这里我们为每个键分配一个默认值,该值也恰好是一个空列表。 br更改为1就是全部更改,因为它们实际上是同一对象!

# 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


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

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

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


,现在使用dict的副本。

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


还是不开心!
我听到有人喊叫,这是因为我使用了一个空列表!

>>> 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']}


empty_list的默认行为是将fromkeys()分配给该值。

>>> 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']}


确实,所有值都相同( None
现在,让我们以多种方式之一遍历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


嗯看起来和以前一样!

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

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


但它们确实是不同的dict s,在这种情况下,这是预期的结果。

评论


所以我们必须迭代吗?

–lucid_dreamer
18年1月25日在2:46

#3 楼

您可以使用此功能:

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


#4 楼

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