在Python字典中向列表追加元素

153 投票
3 回答
401894 浏览
提问于 2025-04-27 13:55

有没有更优雅的方式来写这段代码呢?

我在做的事情是:我有一些键和日期。每个键可以对应多个日期,所以我想创建一个字典,里面存放每个键对应的日期列表。下面的代码可以正常工作,但我希望能有一种更优雅、更符合Python风格的方法。

dates_dict = dict() 
for key,  date in cur:
    if key in dates_dict:
        dates_dict[key].append(date)
    else:
        dates_dict[key] = [date] 

我本来期待下面的代码能正常运行,但我一直收到一个错误,提示NoneType没有append这个属性。

dates_dict = dict() 
for key,  date in cur:
    dates_dict[key] = dates_dict.get(key, []).append(date) 

这可能和下面这个有关

print([].append(1)) 
None 

但为什么会这样呢?

暂无标签

3 个回答

7

dates_dict[key] = dates_dict.get(key, []).append(date) 这行代码会把 dates_dict[key] 设置为 None,因为 list.append 方法返回的就是 None

In [5]: l = [1,2,3]

In [6]: var = l.append(3)

In [7]: print var
None

你应该使用 collections.defaultdict

import collections
dates_dict = collections.defaultdict(list)
39

有没有更优雅的方式来写这段代码?

可以使用 collections.defaultdict

from collections import defaultdict

dates_dict = defaultdict(list)
for key, date in cur:
    dates_dict[key].append(date)
246

list.append 返回的是 None,因为它是在原地操作,也就是说它直接修改了原来的列表,而你却把这个返回值赋值给了 dates_dict[key]。所以,下次你用 dates_dict.get(key, []).append 时,实际上是在对 None.append 进行操作。这就是为什么会出错的原因。相反,你可以直接这样做:

dates_dict.setdefault(key, []).append(date)

不过,我们有一个叫做 collections.defaultdict 的工具,专门用来解决这个问题。你可以这样做:

from collections import defaultdict
dates_dict = defaultdict(list)
for key, date in cur:
    dates_dict[key].append(date)

这样,如果字典中找不到这个 key,就会创建一个新的列表对象。

注意:因为 defaultdict 会在找不到键时创建一个新的列表,这可能会带来意想不到的副作用。例如,如果你只是想获取一个不存在的键的值,它会创建一个新的列表并返回。

撰写回答