Когда использовать понимание списка против цикла for - PullRequest
0 голосов
/ 11 марта 2020

Существует ли общее правило, когда понимание списка предпочтительнее, чем for l oop? Например:

Сингл для l oop отлично подходит для преобразования в понимание:

l = []
for word in sentence:
    l.append(word)

# [word for word in sentence]

Двойной тоже может быть:

l = []
for word in sentence:
    for letter in word:
        l.append(letter)

# [letter for word in sentence for letter in word]

Однако Я думаю, что читаемость становится довольно плохой после этого. Например, с if s:

l = []
for word in sentence:
    if word.startswith('u'):
        for letter in word:
            if letter in ('a', 'b', 'c', 'o'):
                l.append(letter)

# [letter for word in sentence if word.startswith('u') for letter in word if letter in ('a', 'b', 'c', 'o')]

Существует ли предположение о сложности паттерна for l oop, когда было бы хуже пытаться поместить его в понимание списка?

Ответы [ 3 ]

4 голосов
/ 11 марта 2020

Ответ зависит от вашего мнения. Однако, так как я помню конкретный c совет этого автора от автора книги, который пользуется уважением в сообществе Python, я могу поделиться следующей выдержкой из книги Лучано Python 'Свободно * * Рамалхо:

A для l oop может использоваться для выполнения множества разных задач: сканирования последовательности для подсчета или выбора элементов, вычисления агрегатов (сумм, средних значений) или любого другого числа обработки задания. [...] В отличие от этого, listcomp предназначен только для одной цели: для создания нового списка.

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

Если вы ничего не делаете с созданным списком, вы не должны использовать этот синтаксис.

Кроме того, старайтесь, чтобы оно было коротким. Если понимание списка занимает более двух строк, то, вероятно, лучше разбить его на части или переписать как простое старое для l oop. Примите правильное решение: для Python, как для Engli sh, не существует жестких правил быстрого написания.

2 голосов
/ 11 марта 2020

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

import timeit

def squares(size):
    result = []
    for number in range(size):
        result.append(number*number)
    return result

def squares_comprehension(size):
    return [number*number for number in range(size)]

print(timeit.timeit("squares(50)", "from __main__ import squares", number = 1_000_000))
print(timeit.timeit("squares_comprehension(50)", "from __main__ import squares_comprehension", number = 1_000_000))

5.4292075
4.1652729000000015

Надеюсь, это поможет.

1 голос
/ 11 марта 2020

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

from itertools import chain
sentence = "flat is better than nested"

words = sentence.split()
f_words = (w for w in words if w.startswith('f'))
f_chars = chain(*f_words)
good_chars = [c for c in f_chars if c in 'abco']
...