如何缩进Python列表parsing?
列表parsing在某些情况下可能是有用的,但是它们也可能是相当可怕的阅读。作为一个稍微夸张的例子,你将如何缩进?
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 ...]
这样每个expression式都有自己的路线。
如果任何一行变得太大,我喜欢用lambda或expression式将其提取出来:
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 ) ]
对我来说太过分了 也许这只是一个可怕的例子,因为“types”和“删除”显然是数据库查询的一部分。
我倾向于认为,如果一个列表理解跨越多行,它可能不应该是一个列表理解。 话虽如此,我通常只是像“其他人”那样在“如果”这个东西上分裂,并且会在这里回答。
allUuids = [x.id for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) if x.type == "post" and x.deleted is not False]
你不应该使用列表理解 。
列表parsing是一个很棒的function,但是它们只是捷径,而不是普通的代码。
对于如此长的片段,您应该使用普通的区块:
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)
完全一样的行为,更可读。 圭多会为你感到骄傲:-)
怎么样:
allUuids = [x.id for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) if (x.type == "post" and x.deleted is not False)]
一般来说,通过预先计算variables的子expression式可以避免长行,这可能会增加一个很小的性能成本:
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" and x.deleted)
如果你在理解上设定的话, 那么这个答案是很好的。
对于更复杂的理解,我build议使用带有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