Рубрики
Без рубрики

Советы Python: избегайте большого понимания списка

Как хорошо известно, понимание списка Python работает быстрее, чем петли. Тем не менее, есть ситуации, когда … Tagged с помощью Python, понимания, генераторов, generatorexpressions.

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

Синтаксически, эти два очень похожи. Единственная разница между ними заключается в том, что вы объявляете понимание списка с [] и выражения генератора с () , именно так:

list_compr = [x**2 for x in range(10)]
gen_expr = (x**2 for x in range(10))

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

>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Выражение генератора, напротив, вернет объект генератора:

>>> (x**2 for x in range(10))
 at 0x0000023DD840F7C8>

Чтобы он работал, нам нужно либо использовать Next () Метод, итерация над выражением генератора или используйте такие методы, как list () , set () , или Tuple () Анкет

В приведенных выше примерах использование понимания списка на самом деле более предпочтительно. Когда память не является проблемой, они превосходят выражения генератора.

Проблема возникает, когда вам нужно обрабатывать действительно большие объемы данных, потому что понимание списков хранят все свои выводы в памяти одновременно (как мы только что видели в нашем коде).

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

Также упоминается, что выражения генератора особенно полезны с такими функциями, как sum () , min () и max () Анкет

У них также есть еще одно преимущество. Выражения генератора могут легко объединить (составлено) вместе, создавая тем самым конвейер данных, который может обрабатывать огромные объемы элемента данных по элементу.

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

Давайте выполним небольшой тест, а также посмотрим, как выражения генератора могут быть прикованы вместе. Мы собираемся: 1) подсчитывать длину каждой строки в файле, 2), затем извлеките квадратный корень из каждой длины линии, 3) подводят суммирование квадратных корней. Конечно, этот пример будет более учебным.

Я собираюсь использовать «Приключения Шерлока Холмса» в формате .txt, который вы можете скачать здесь Если вы хотите практиковать себя. Вы можете выбрать другой текстовый файл.

Давайте сначала использовать список понимания:

import time

execution = []
for i in range(100):
    start = time.time()
    filename = 'Sherlock Holmes.txt'
    lengths = [len(line) for line in open(filename)]
    roots = [x**0.5 for x in lengths]
    print(sum(roots))
    end = time.time()
    execution.append(end-start)
print(f'Avg execution time with list comprehensions: '
      f'{sum(execution)/len(execution):.5f}')

С выражениями генератора этот код будет выглядеть почти таким же:

import time

execution = []
for i in range(100):
    start = time.time()
    filename = 'Sherlock Holmes.txt'
    lengths = (len(line) for line in open(filename))
    roots = (x**0.5 for x in lengths)
    print(sum(roots))
    end = time.time()
    execution.append(end-start)
print(f'Avg execution time with generator expressions: '
      f'{sum(execution)/len(execution):.5f}')

Второй кусок будет работать по -другому. Вместо того, чтобы создавать весь результат на каждой строке, Python будет читать одну строку из файла, затем измерить его длину и добавить его в сумму. Затем переводчик перейдет к следующей строке и т. Д. Это именно то, что означает выражения генератора цепочки (сочинение) генератора в конвейер данных.

Итак, давайте запустим обе версии:

Avg execution time with list comprehensions: 0.00486
Avg execution time with generator expressions: 0.00530

Как видите, в этом наборе данных список понимания работает быстрее. Но если я запускаю один и тот же код в файле, который содержит более 10 миллионов строк на моей машине, результаты будут разными (я просто копировал текст в моем Шерлоке Холмсе много раз):

Avg execution time with list comprehensions: 4.26855
Avg execution time with generator expressions: 3.79113

Как видите, в этом случае выражения генераторов побили понимание:)

ВЫВОД

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

В то же время, от небольших данных (сколько меньше – зависит от машины), перечисленные понимания обычно превосходят выражения генератора, и они могут быть более полезными, если вам необходимо получить доступ к созданным данным более одного раза.

Если вам хочется изучать что -то еще, проверьте мой предыдущий пост, где я говорю, когда хорошо использовать Deques вместо списков.

Подключите меня на LinkedIn.

Оригинал: “https://dev.to/v_it_aly/python-tips-avoid-large-list-comprehensions-4jl0”