繁体   English   中英

如何缩进 Python 列表理解?

[英]How to indent Python list-comprehensions?

列表推导在某些情况下可能很有用,但它们读起来也很糟糕。作为一个稍微夸张的例子,您将如何缩进以下内容?

allUuids = [x.id for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) if x.type == "post" and x.deleted is not False]

这取决于他们有多长。 我倾向于像这样构造它们:

[x.id for x
 in self.db.query(schema.allPostsUuid).execute(timeout=20)
 if x.type == 'post' 
    and x.deleted is not False
    and ...
    and ...]

这样每个表达式都有自己的行。

如果任何行变得太大,我想在lambda或表达式中提取它:

transform = lambda x: x.id
results = self.db.query(schema.allPostsUuid).execute(timeout=20)
condition = lambda x: x.deleted is not False and ... and ...
[transform(x) for x in results if condition(x)]

然后,如果一个lambda变得太长,它会被提升为一个函数。

在我工作的地方,我们的编码指南会让我们做这样的事情:

all_posts_uuid_query = self.db.query(schema.allPostsUuid)
all_posts_uuid_list = all_posts_uuid_query.execute(timeout=20)
all_uuid_list = [
    x.id 
    for x in all_posts_uuid_list 
    if (
        x.type == "post" 
        and 
        not x.deleted  # <-- if you don't care about NULLs / None
    )
]
allUuids = [x.id 
            for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) 
            if x.type == "post" and x.deleted is not False]

对我来说太多了。 也许这只是一个可怕的例子,因为“type”和“deleted”显然是db查询的一部分。

我倾向于认为如果列表理解跨越多行,那么它可能不应该是列表理解。 话虽如此,我通常只是像其他人一样将这个东西拆分为“if”并在这里回答。

你不应该使用列表理解

列表推导是一个很棒的功能,但它们应该是快捷方式,而不是常规代码。

对于这么长的片段,你应该使用普通的集团:

allUuids = []
for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) :
    if x.type == "post" and x.deleted is not False :
        allUuids.append(x.id)

完全相同的行为,更具可读性。 圭多会为你感到自豪:-)

如果你理解了,那么你的答案是好的。

对于更复杂的理解,我建议使用带有yield的生成器:

allUuids = list(self.get_all_uuids())


def get_all_uuids(self):
    for x in self.db.query(schema.allPostsUuid).execute(timeout = 20):
        if x.type == "post" and x.deleted is not False:
            yield x.id

怎么样:

allUuids = [x.id for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) 
                   if (x.type == "post" and x.deleted is not False)]

通常,可以通过将子表达式预先计算为变量来避免长行,这可能会增加极小的性能成本:

query_ids = self.db.query(schema.allPostsUuid).execute(timeout = 20)
allUuids = [x.id for x in query_ids
                   if (x.type == "post" and x.deleted is not False)]

顺便说一句,是不是' is not False '那种多余的? 你是否担心区分None和False? 因为否则,只需将条件保留为:i f (x.type == "post" and x.deleted)

    allUuids = [
        x.id
        for x in self.db.query(schema.allPostsUuid).execute(timeout = 20)
        if x.type == "post"
            and x.deleted
    ]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM