如何缩进Python列表理解?

如何缩进Python列表理解?,python,coding-style,Python,Coding Style,列表理解在某些情况下可能有用,但阅读起来也可能相当糟糕。。作为一个稍微夸张的例子,您将如何缩进以下内容 allUuids = [x.id for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) if x.type == "post" and x.deleted is not False] 那么: allUuids = [x.id for x in self.db.query(schema.allPostsUuid).e

列表理解在某些情况下可能有用,但阅读起来也可能相当糟糕。。作为一个稍微夸张的例子,您将如何缩进以下内容

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

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
”不是有点多余吗?您是否担心区分“无”和“假”呢?因为否则,只将条件保留为:i
f(x.type==“post”和x.deleted)
对我来说太多了。也许这只是一个糟糕的例子,因为“type”和“deleted”显然是db查询的一部分


我倾向于认为,如果一个列表理解跨越多行,它可能不应该是一个列表理解。话虽如此,我通常会像其他人一样,在“如果”这个词上分开,然后在这里回答。

这取决于他们的时间长短。我倾向于这样组织它们:

[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
    )
]
all\u posts\u uuid\u query=self.db.query(schema.allpostsuid)
所有帖子\u uuid\u列表=所有帖子\u uuid\u查询。执行(超时=20)
所有用户ID列表=[
x、 身份证
对于所有帖子列表中的x
如果(
x、 类型==“post”
及

不是x。已删除#您不应该使用列表理解来进行此操作

列表理解是一个很棒的特性,但它们是快捷方式,而不是常规代码

对于如此长的代码段,您应该使用普通的blocs:

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)

完全相同的行为,更具可读性。Guido会为你感到骄傲:-)

如果你的理解力很好

对于这样更复杂的理解,我建议使用带有
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

我同意。一般来说,在所有语言中都应该避免超过80个字符的行。我同意,但Python的语法规则通常鼓励/强制使用更长的行。它的空白处理通常是我对该语言唯一的抱怨。对于精心选择的变量,以及用括号或方括号分隔行,我从不需要使用to关于“顺便说一句”的行太长(问题往往是为了避免self.long_foo.very_long_bar.baz(..)使用临时词),这并不是完全多余的,例如,以x.deleted=None为例。这些都是不等价的-列表理解速度要快很多倍,因为它不必进行任何函数查找。适当的转换将用于循环。除了性能影响之外,这是一个非常可读的示例!for循环如何阻止函数n lookup?还要注意,列表理解中的循环是用C实现的,因此比普通的循环要快。只需注意——您可以使用多个if语句,而不是使用“and”多次。这是一个有趣的小语法事实。并非所有使用Python的人都是数据科学家或从事ML工作,因此对于普通人来说,只处理API中仅有100个项目的响应,第二个版本就可以了。但是我仍然更喜欢第一个。这稍微慢一点,因为你必须一步一步地构建数组。我认为st comprehension在幕后的作用完全相同。这并不是因为它是一个单行表达式,所以这是一个一次性操作……e-statis:函数是一样的,但列表理解可以非常快。在Python文化中,您通常选择可读性而不是速度。Python毕竟不是一种快速语言……这种方式使用了mutable、 非函数式风格。不变性允许从映射和筛选的角度进行思考。在本代码中,列表是更改的,读者必须记住,它可以在以后更改。最好让带有
的生成器函数产生
,或者引入新的变量和函数。
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