列表解析在某些情況下可能有用,但它們也可能相當可怕地閱讀。作爲一個稍微誇張的示例,您將如何縮進以下內容?如何縮進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]
列表解析在某些情況下可能有用,但它們也可能相當可怕地閱讀。作爲一個稍微誇張的示例,您將如何縮進以下內容?如何縮進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 ...]
這樣每個表達式都有它自己的行。
如果任何線變得太大,我想提取出來的拉姆達或表達式:
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變得太長時間被提升到一個函數。
如何:
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" and x.deleted)
對我來說這太多了。也許這只是一個可怕的例子,因爲「type」和「deleted」顯然是db查詢的一部分。
我傾向於認爲,如果一個列表理解跨越多行,它可能不應該是一個列表理解。話雖如此,我通常只是在「如果」像其他人一樣將事物分解並在這裏回答。
我在哪裏工作,我們的編碼準則將讓我們做這樣的事情:
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]
你不應該使用列表理解爲。
列表解析是一個很棒的功能,但它們的目的是作爲捷徑,而不是普通的代碼。
這麼長的片段,你應該使用普通集團:
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)
完全一樣的行爲,更具有可讀性。圭多會爲你感到驕傲:-)
如果你設置了理解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
我第二次說。在所有語言中應避免使用超過80個字符的行。 – 2008-11-22 18:19:22
同意,但Python的語法規則通常會鼓勵/強制更長的行。它的空白處理通常是關於我對語言的唯一抱怨。 – 2008-11-22 18:27:59
通過仔細選擇變量,並用括號或括號分割線條,我從來不必訴諸太長的線條(問題更多的是爲了避免self.long_foo.very_long_bar.baz(....)使用臨時對象) – 2008-11-22 18:33:31