Как сделать отступ в списках 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]
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
70
0
24 515
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Как насчет:

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

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

Piotr Lesnicki 22.11.2008 21:19

Согласен, но правила синтаксиса Python часто поощряют / заставляют строки становиться длиннее. Его обработка пробелов в целом - это моя единственная жалоба на язык.

Peter Rowell 22.11.2008 21:27

Благодаря тщательно подобранным переменным и разделению строк скобками или скобками мне никогда не приходилось прибегать к слишком длинным строкам (чаще проблема заключается в том, чтобы избежать self.long_foo.very_long_bar.baz (....) с использованием временных библиотек)

Piotr Lesnicki 22.11.2008 21:33

Насчет «Между прочим», это не совсем лишнее, например, случай x.deleted = None.

Ali Afshar 22.11.2008 22:05

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

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

Ответ принят как подходящий

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

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

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

они НЕ эквивалентны - понимание списка происходит во много раз быстрее, так как не требуется выполнять поиск функций. соответствующий перевод будет использовать для циклов.

Claudiu 22.11.2008 22:38

За исключением падения производительности, это очень читаемый пример!

Geo 22.11.2008 22:51

Как циклы for предотвратят поиск функции? Также обратите внимание, что цикл в понимании списков реализован в C и, следовательно, быстрее, чем простой.

orestis 22.11.2008 23:01

Просто примечание - вы можете использовать несколько операторов if вместо многократного использования «и». Этакая забавная синтаксическая правда.

cdleary 24.11.2008 08:17

Не все, кто использует Python, являются специалистами по данным или занимаются машинным обучением, поэтому для обычных людей, которые просто работают с ответами от API, в которых содержится всего несколько 100 элементов, вторая версия подойдет. Однако я все же предпочитаю первый.

Asfand Qazi 19.12.2018 14:48

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

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)

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

это немного медленнее, так как вам нужно строить массив шаг за шагом

Claudiu 22.11.2008 22:59

Я думаю, что понимание списка делает то же самое под капотом. Это одноразовая операция не потому, что это однострочное выражение ...

e-satis 23.11.2008 00:31

e-statis: функция та же, но понимание списков может быть значительно быстрее

orip 23.11.2008 02:58

Хм, у меня нет времени тестировать его, так что придется поверить тебе на слово :-) Но в любом случае удобочитаемость имеет большее значение, чем скорость в Python ...

e-satis 23.11.2008 03:22

В культуре Python вы обычно предпочитаете удобочитаемость скорости. В любом случае Python - не быстрый язык ...

e-satis 28.04.2009 19:25

Таким образом используется изменчивый нефункциональный стиль. Неизменяемость позволяет мыслить в терминах отображения и фильтрации. В этом коде список изменен, и читатель должен иметь в виду, что он может быть изменен впоследствии. Лучше заставить генератор работать с yield, чем это, или ввести новые переменные и функции.

George Sovetov 24.07.2016 19:23

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

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

Другие вопросы по теме