首页 > 解决方案 > 如何正确使用 dic.setdefault(key,[]).append()

问题描述

a=[{'kart': ['alice', 'marie'],
  'vinod': ['alice', 'marie'],
  'jordan': ['alice', 'marie'],
  'joe': ['marie', 'alice']},
 {'kart': ['alice', 'marie'],
  'vinod': ['alice', 'marie'],
  'jordan': ['alice', 'marie'],
  'joe': ['marie', 'alice']},
 {'kart': ['alice', 'marie'],
  'vinod': ['alice', 'marie'],
  'jordan': ['alice', 'marie'],
  'joe': ['marie', 'alice']}]

我有上面的字典列表。我想要通过将字符串附加到 a[0] 的键或列表中的第一个元素来获得所需的输出。

期望的输出:

{'kart': ['marie', 'alice', 'elsie'],
 'vinod': ['alice', 'marie'],
 'jordan': ['marie', 'alice'],
 'joe': ['marie', 'alice']}

我得到的输出:

{'kart': ['alice', 'marie', 'elsie'],
 'vinod': ['alice', 'marie', 'elsie'],
 'jordan': ['alice', 'marie', 'elsie'],
 'joe': ['alice', 'marie', 'elsie']}  

我正在使用的代码:

 import copy
 dic_copy=copy.deepcopy(a[0])
 dic_copy.setdefault("kart",[]).append("elsie")

出于某种原因,当我只想要一个键时,上面的代码会附加到字典中的所有键上。任何建议都会有所帮助!

标签: pythonlistdictionaryappend

解决方案


您的问题是,您以某种方式使用指向同一列表的键创建字典,而不是四个相等的列表。这意味着一旦您更改了单个值,所有其他值似乎也会更改(实际上,它只是单个对象)。

您的 setdefault 完全没问题,它是“设置或获取 && 返回”。

你的情况:

>>> names = ['marie', 'alice']
>>> d = {k: names for k in ['kart', 'vinod', 'jordan', 'joe']}
>>> d.setdefault('kart', []).append('elsie')
>>> d
{'kart': ['marie', 'alice', 'elsie'],
 'vinod': ['marie', 'alice', 'elsie'],
 'jordan': ['marie', 'alice', 'elsie'],
 'joe': ['marie', 'alice', 'elsie']}

将 dict 创建更改为{k: names[:] for k in ...}您所期望的 - 名称将相同,但对象不同。

要检查这一点,请尝试使用 进行身份检查is,即:

>>> d['kart'] is d['joe']  # will be True in your case

棘手的是deepcopy不改变结构。因此,如果您的 dict 具有指向同一列表的键,则该 dict 的深层副本将具有相同的结构。

如果您已经在此结构中进行了 dict,并且希望在值中具有不同的身份,则可以像这样重新创建它:

>>> names = ['marie', 'alice']
>>> d = {k: names for k in ['kart', 'vinod', 'jordan', 'joe']}
>>> d['kart'] is d['joe']
True

>>> d = {k:v[:] for k, v in d.items()}
>>> d['kart'] is d['joe']
False

推荐阅读