Как сделать отступ в списках Python? - PullRequest
57 голосов
/ 22 ноября 2008

Понимания списка могут быть полезны в определенных ситуациях, но их также может быть довольно ужасно читать. В качестве слегка преувеличенного примера, как бы вы выделили следующее?

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

Ответы [ 7 ]

63 голосов
/ 22 ноября 2008

Зависит от того, как долго они. Я склонен структурировать их так:

[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)]

И затем, если лямбда становится слишком длинной, она превращается в функцию.

43 голосов
/ 22 ноября 2008

Где бы я ни работал, наши правила кодирования заставили бы нас сделать что-то вроде этого:

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
    )
]
7 голосов
/ 22 ноября 2008
allUuids = [x.id 
            for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) 
            if x.type == "post" and x.deleted is not False]
5 голосов
/ 22 ноября 2008

Для меня это слишком много. Может быть, это просто ужасный пример, так как "type" и "удалено" явно будут частью запроса db.

Я склонен думать, что если понимание списка занимает несколько строк, вероятно, это не должно быть понимание списка. Сказав это, я обычно просто делю эту вещь на «если», как и другие люди, и отвечу здесь.

3 голосов
/ 16 декабря 2015

Если вы настроены на понимание Ответ Орестиса - это хорошо.

Для более сложных понятий я бы предложил использовать генератор с 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
3 голосов
/ 22 ноября 2008

Вы не должны использовать списки для этого .

Понимание списков - потрясающая функция, но они должны быть ярлыками, а не обычным кодом.

Для такого длинного фрагмента вы должны использовать обычные блоки:

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)

Точно такое же поведение, гораздо более читабельное. Гвидо гордился бы вами: -)

1 голос
/ 22 ноября 2008

Как насчет:

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)]

Кстати, разве "1007" не лишнее? Вас беспокоит различие между None и False? Потому что в противном случае достаточно оставить условие как: i f (x.type == "post" and x.deleted)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...