2008-11-22 2 views
46

В некоторых ситуациях могут быть полезны списки, но они также могут быть довольно ужасны для чтения. Как слегка преувеличенный пример, как вы могли бы отступать следующим образом?Как отступы в 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] 

ответ

55

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

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

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

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

+0

Я второй это. Обычно на всех языках следует избегать линий более 80 символов. – 2008-11-22 18:19:22

+0

Согласовано, но правила синтаксиса Python часто поощряют/усиливают более длинные строки. Его обработка пробелов в целом касается моей единственной жалобы на язык. – 2008-11-22 18:27:59

+0

С тщательно подобранными переменными и разделительными линиями с круглыми скобками или скобками мне никогда не приходилось прибегать к слишком длинным линиям (проблема чаще всего заключается в том, чтобы избежать self.long_foo.very_long_bar.baz (....) с использованием временных рядов) – 2008-11-22 18:33:31

5

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

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

37

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

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

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

0

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