我需要构建空嵌套字典的大树,并想知道下面的代码是否是Pythonic:
dictionary_name = dict((year, dict((month, dict((day, []) for day in days))
for month in months)) for year in years)
注意:此问题也适用于列表推导。如果您认为我应该将此问题分解为多个问题,请告诉我。
答案 0 :(得分:5)
你上面的内容对我来说有点过于密集......我实际上通常会避免像这样嵌套表达式,因为我很难记住它们是从内到外读取,还是从外面读取,或者通过某种方式读取奇怪的魔法随机方法。也就是说,我知道还有其他人写了很棒的python代码,有时会嵌套,我认为只要你没有嵌套得太深就可以了。
就个人而言,我可能会创建一个dict
,它使用元组对其进行索引 - 我可能会考虑使用defaultdict
:
from collections import defaultdict
dictionary_name = defaultdict(list)
dictionary_name[(year,month,day)].append(data)
#your way would be: `dictionary_name[year][month][day].append(data)`
这是(恕我直言)比你上面的代码更容易理解的代码(即更多的pythonic)。
如果您不想要defaultdict
,可以使用itertools.product
构建字典:
dictionary_name = dict( ( k,[] ) for k in it.product(years,months,days) )
或
dictionary_name = { k:[] for k in it.product(years,months,days) } #py2.7+
答案 1 :(得分:5)
如果您不介意使用defaultdict
,我会选择
from collections import defaultdict
import itertools
dd = defaultdict( defaultdict )
for y, m, d in itertools.product( years, months, days ):
dd[y][m][d] = []
答案 2 :(得分:2)
列表理解的复杂性更多地取决于个人/开发。团队风格比纯粹的“被Pythonic”问题。对于这种情况,一个很好的潜在参考工具是Google Python Style Guide。他们的section on listcomps说:
可以用于简单的案例。
带有“决定”(即Google内部如何解决此问题):
可以用于简单的案例。每个部分必须适合一行:映射表达式,for子句,过滤器表达式。不允许使用多个for子句或过滤器表达式。当事情变得更复杂时,请使用循环。
就个人而言,我会选择嵌套的listcomps ,只要它们可以立即理解,否则会分解为多个部分,功能等。
您的问题的其他说明:
最终,风格问题是“运用你的判断力” - 只需考虑后来遇到你代码的其他开发人员。
答案 3 :(得分:0)
虽然我同意其他海报的说法,这个表达有点密集,如果你 打算写一些密集的东西,以另一种方式分解它可能是一个好主意。一点点缩进调整可以大大提高它的可读性:
dictionary_name = dict(
(year, dict((month, dict((day, [])
for day in days))
for month in months))
for year in years)