在Python字典中向列表追加元素
有没有更优雅的方式来写这段代码呢?
我在做的事情是:我有一些键和日期。每个键可以对应多个日期,所以我想创建一个字典,里面存放每个键对应的日期列表。下面的代码可以正常工作,但我希望能有一种更优雅、更符合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
会在找不到键时创建一个新的列表,这可能会带来意想不到的副作用。例如,如果你只是想获取一个不存在的键的值,它会创建一个新的列表并返回。