列表推导在某些情况下可能很有用,但它们也可能相当可怕阅读..作为一个有点夸张的例子,你会如何缩进以下内容?
allUuids = [x.id for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) if x.type == "post" and x.deleted is not False]
答案 0 :(得分:63)
这取决于它们有多长。我倾向于像这样构造它们:
[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变得太长,它就会被提升为一个函数。
答案 1 :(得分:43)
在我工作的地方,我们的编码指南会让我们做这样的事情:
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
)
]
答案 2 :(得分:7)
allUuids = [x.id
for x in self.db.query(schema.allPostsUuid).execute(timeout = 20)
if x.type == "post" and x.deleted is not False]
答案 3 :(得分:5)
对我而言太过分了。也许这只是一个可怕的例子,因为“type”和“deleted”显然是db查询的一部分。
我倾向于认为如果列表理解跨越多行,则可能不应该是列表理解。话虽如此,我通常只是像其他人一样将这个东西拆分为“if”并在这里回答。
答案 4 :(得分:3)
您不应该使用列表推导。
列表推导是一个很棒的功能,但它们应该是快捷方式,而不是常规代码。
对于这么长的片段,你应该使用普通的集团:
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会为你感到骄傲: - )
答案 5 :(得分:3)
如果你理解orestis's answer是好的。
对于更复杂的理解,我建议使用带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
答案 6 :(得分:1)
怎么样:
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)