用最优雅的方式创建一个值为列表的字典,应该如何做?

3

我有一个类似于以下的东西

retval = {}

# ...
# some code here to fetch data
# ...

for row in cursor.fetchall():
    if row.someid not in retval:
        retval[row.someid] = [dict(zip(columns,rows))]
    else:
        retval[row.someid].append(dict(zip(columns,rows))

这将产生:

retval = {
    1: [{'someid': 1, 'samplefield': 'valueX', ... },
        {'someid': 1, 'samplefield': 'valueY', ... }],
    2: [{'someid': 2, 'samplefield': 'valueX', ... }]
    }

我觉得有更符合Python风格的方法来达到我需要的结果。

确切地说,是否有一种方法可以减少这些代码行:

if row.someid not in retval:
    retval[row.someid] = [dict(zip(columns,rows))]
else:
    retval[row.someid].append(dict(zip(columns,rows))

如何将内容放在单行中?

答案: 其实在文档中早就有了!感谢Christian Ternuschthonicdaemon指点我正确的方向。我更新了这篇文章,因为我发现文档中有多种方法可以实现。

from collections import defaultdict
retval = defaultdict(list) ## Or retval = defaultdict(lambda: []) based on my accepted answer.

# ...
# some code here to fetch data
# ...

for row in cursor.fetchall():
    retval[row.someid].append(dict(zip(columns,rows))

或者

retval = {} 

# ...
# some code here to fetch data
# ...

for row in cursor.fetchall():
    retval.setdefault(row.someid, []).append(dict(zip(columns,rows))

希望这篇文章能像对我有帮助一样,对你也有所裨益!
1个回答

3

尝试使用内置的collections模块中的defaultdict

from collections import defaultdict
retval = defaultdict(lambda: [])

# ...
# some code here to fetch data
# ...

for row in cursor.fetchall():
    retval[row.someid].append(dict(zip(columns,rows))

5
defaultdict(list)比使用lambda更好一些。 - chthonicdaemon
非常感谢。在接受作为正确答案之前,我将首先在我的实际应用程序中尝试它。这也相当快! - Eduard
@chthonicdaemon 有没有特定的原因,说明为什么 defaultdict(list) 比 lambda 更好? - Eduard
@EduardDaduya 对我来说,使用list似乎更加直观,因为list的行为与lambda: []完全相同。构建一个返回值的函数涉及到比仅仅传递对现有对象的引用更多的机制。 - chthonicdaemon
2
@chthonicdaemon Meh: 在[7]中:%timeit defaultdict(list) 最慢的运行时间比最快的运行时间长11.56倍。这可能意味着一个中间结果被缓存了。 10000000个循环,3次中的最佳:每个循环165纳秒在[8]中:%timeit defaultdict(lambda:[]) 1000000个循环,3次中的最佳:每个循环186纳秒 我个人认为,对于人类读者来说更容易理解,这才是最重要的。 - Christian Ternus
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接