附加到 Python 字典中的列表 [重复]

Posted

技术标签:

【中文标题】附加到 Python 字典中的列表 [重复]【英文标题】:Appending to list in Python dictionary [duplicate] 【发布时间】:2014-12-09 15:50:49 【问题描述】:

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

我在做什么:我有钥匙和日期。可以为一个键分配多个日期,因此我正在创建一个日期列表字典来表示这一点。以下代码工作正常,但我希望有一个更优雅和 Pythonic 的方法。

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

我期待下面的工作,但我不断收到 NoneType has no attribute append 错误。

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

这可能与以下事实有关

print([].append(1)) 
None 

但是为什么?

【问题讨论】:

你应该看看collections.defaultdict 你可以尝试使用 extend() 而不是 append() for key, date in cur: - cur 是什么? @Mawg 这是不久前的事了,但我可能正在使用与 Python 的 sqlite3 库关联的游标对象。 【参考方案1】:

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)

【讨论】:

是的,我就是这么想的。因为没有返回值。它将返回 None 作为默认值。谢谢 @MichaelMurphy,使用 defaultdict 将是做你想做的最有效的方法【参考方案2】:

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 将创建一个新列表,这将产生意想不到的副作用。例如,如果您只是想检索一个不存在的键的值,它将创建一个新列表并返回它。

【讨论】:

@chepner:请注意,除了__getitem__() 之外的任何操作都不会调用__missing__()。这意味着get() 将像普通字典一样返回None 作为默认值,而不是使用default_factory,即key in dates_dictdates_dict.get(key) 按预期工作 作为后续。我最终使用了 setdefault,因为这个 git 正是我想要的,而不需要额外的导入。感谢您的帮助 您对[].append 为何返回None 的解释对我来说没有意义。如果您要立即分配或打印它,为什么它是就地操作很重要?为什么dates_dict.get(key, []).append 会产生None 除非dates_dict[key] == None 没错!在其中一次迭代中,append 的结果存储在 key 中,并使用 get 检索并附加。但这次不是列表而是无 使用 defaultdict 比使用 setdefault 有什么好处?【参考方案3】:

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

使用collections.defaultdict:

from collections import defaultdict

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

【讨论】:

当我尝试for key, date_list in dates_dict: 时,我得到error: too many values to unpack (expected 2) @Mawg 查看答案中的代码。我在那里看不到你的例子。 @Axl 查看答案和评论中的代码。你看出区别了吗? (注意:curdates_dict 不同——它们是不同的对象)

以上是关于附加到 Python 字典中的列表 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 setdefault 之后附加到字典中的列表 [重复]

Python:将 a 附加到字典中的列表

For循环正在覆盖列表中的字典值[重复]

将项目附加到列表列表中的指定列表(Python)[重复]

附加到python中的空列表时出错[重复]

将值附加到字典中的一个列表 将值附加到字典中的所有列表