Как отступать от списка Python?

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

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

Ответ 1

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

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

А затем, если лямбда становится слишком длинной, она получает повышение до функции.

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

Вам не следует использовать понимание списка для.

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

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

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)

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

Ответ 6

Как насчет:

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" видом лишнего? Вы беспокоитесь о различии между Нием и Ложь? Поскольку в противном случае достаточно оставить условие только: я f (x.type == "post" and x.deleted)

Ответ 7

Если вы настроены на понимание orestis 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