Python dict如何创建密钥或向密钥添加元素?


161

我有一本空字典。名称:dict_x 将具有其值为列表的键。

从一个单独的迭代中,我获得一个键(例如:)key_123和一个项目(一个元组),将其放置在dict_xvalue 的列表中key_123

如果该键已经存在,我想添加此项。如果此键不存在,我想用一个空列表创建它,然后追加到它或只在其中添加一个元组。

将来再次出现此键时,由于它存在,我希望再次添加该值。

我的代码包含以下内容:

获取关键和价值。

看看中是否存在NOTdict_x

如果没有创建它: dict_x[key] == []

之后: dict_x[key].append(value)

这是这样做的方式吗?我应该尝试使用try/except积木吗?

Answers:


253

用途dict.setdefault()

dic.setdefault(key,[]).append(value)

help(dict.setdefault)

    setdefault(...)
        D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D

4
我曾经这样做,dict_x[key] = [some_value] if not dict_x.has_key(key) else dict_x[key] + [some_value]但是这个答案提出了一种更好的方法。实际上,它set()作为一个参数并允许您使用add()方法...
fatih_dur

66

这是执行此操作的各种方法,因此您可以比较它的外观并选择所需的内容。我以我认为最“ pythonic”的方式对它们进行了排序,并评论了乍一看可能并不明显的利弊:

使用collections.defaultdict

import collections
dict_x = collections.defaultdict(list)

...

dict_x[key].append(value)

优点:可能是最佳性能。缺点:在Python 2.4.x中不可用。

使用dict().setdefault()

dict_x = {}

...

dict_x.setdefault(key, []).append(value)

缺点:未使用list()s的创建效率低。

使用try ... except

dict_x = {}

...

try:
    values = dict_x[key]
except KeyError:
    values = dict_x[key] = []
values.append(value)

要么:

try:
    dict_x[key].append(value)
except KeyError:
    dict_x[key] = [value]

您好,您为什么认为.setdefault创建不必要的字典?
Phil

2
我认为不会.setdefault()创建不必要的字典。我认为我正在第二个参数中创建不必要的lists(即,如果已经存在,则永远不会使用)。我可以使用(为了有效地进行键哈希处理),并使用一个变量来重用未使用的s,但这又增加了几行代码。[].setdefault()keydict.setdefault()list
安塔克2012年

1
IIRC,在Python中,等式中的空列表被视为字节码级别的常量,但这需要字节码专家进行一些确认(或仅使用disas模块)。
令人惊讶的2015年

使用.setdefault创建常规的dict地方缺席键查找将导致KeyError同时collections.defaultdict(list)创建一个dict在那里缺少键查找将插入一个空的list-我想你应该根据你想要的行为选择
Chris_Rands

我在自己的代码中尝试了类似于collections.defaultdict的操作,它具有意外的副作用。例如,考虑以下IDLE交换:>>> list_dict = defaultdict(list)>>> len(list_dict)0 >>> len(list_dict [0])0 >>> len(list_dict)1看来当Python调用时默认值会将键添加到字典中,而无需您主动设置它,如果使用过多默认值,则会创建很多空列表。我将为字典推出自己的包装函数,虽然效率低下,但希望可以预测更多。
RDBury

26

您可以为此使用defaultdict

from collections import defaultdict
d = defaultdict(list)
d['key'].append('mykey')

这比setdefault没有创建最终不会使用的新列表要有效得多。每次调用setdefault都会创建一个新列表,即使该条目已存在于字典中也是如此。


14

您可以使用defaultdictcollections

来自doc的示例:

s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d = defaultdict(list)
for k, v in s:
    d[k].append(v)

0
dictionary['key'] = dictionary.get('key', []) + list_to_append

1
您应该解释在某些例外情况下这具有的(非常小的)好处;仅作为代码,尚不清楚为什么需要附加答案。
戴维斯·鲱鱼

嗨,这是没有其他导入的替代方法。显然,可以使用if语句完成此操作。我只是建议使用.get()的功能替代使用dict []。
Tomas Silva Ebensperger

前两个答案提到了两种不导入的方式(尽管不是dict.get)。
戴维斯鲱鱼
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.