1

我需要构建空嵌套字典的大树,并想知道下面的代码是否是 Pythonic:

dictionary_name = dict((year, dict((month, dict((day, []) for day in days))
                       for month in months)) for year in years)
  • 如果这是不好的做法,那么编写上述代码的最 Pythonic 方式是什么?
  • 如果这不是坏习惯,我应该在哪里使用换行符来保持这个清晰和“Pythonic”。此外,在嵌套生成器时,它们的速度优势是否仍然存在?

注意:这个问题也适用于列表推导。如果您认为我应该将这个问题分成多个问题,请告诉我。

4

4 回答 4

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+
于 2012-10-19T13:18:02.783 回答
5

如果您不介意使用 a defaultdict,我会选择

from collections import defaultdict
import itertools
dd = defaultdict( defaultdict )
for y, m, d in itertools.product( years, months, days ):
    dd[y][m][d] = []
于 2012-10-19T13:20:20.100 回答
2

列表理解的复杂性更多是个人/开发的问题。团队风格而不是纯粹的“Pythonic”问题。Google Python Style Guide是此类情况的一个很好的潜在参考工具。他们关于 listcomps 的部分说:

可以用于简单的情况。

有一个“决定”(即谷歌内部如何解决这个问题):

可以用于简单的情况。每个部分必须适合一行:映射表达式、for 子句、过滤器表达式。不允许使用多个 for 子句或过滤器表达式。当事情变得更复杂时,请使用循环。

就个人而言,我会选择嵌套的 listcomps ,只要它们可以立即理解,否则会分解为多个部分、函数等。

您的问题的其他说明:

  • 是的,您可以在 listcomps 中进行换行,这有时有助于提高可读性。
  • 对于速度,答案是“视情况而定”,并且可能更多的是 Stack Overflow 的一个单独问题(我非常有信心您会在这里找到一些好的起点)。如果不出意外:(1)确保这是一个瓶颈,然后(2)基准替代品。

归根结底,风格问题是“使用你的判断”的问题——只要考虑到其他开发人员以后会遇到你的代码。

于 2012-10-19T13:18:06.623 回答
0

虽然我同意其他海报的观点,这个表达式有点密集,用另一种方式分解它可能是个好主意,如果你要写一些密集的东西,一点缩进调整可以很长的路要走使其更具可读性:

dictionary_name = dict(
    (year, dict((month, dict((day, [])
                             for day in days))
                for month in months))
    for year in years)
于 2012-10-19T13:52:03.793 回答