Когда использовать функции генератора и когда использовать циклы в Python - PullRequest
0 голосов
/ 06 октября 2019

Я из истории Matlab, и мне трудно обойти концепцию генераторов в Python.

Может ли кто-нибудь ответить мне следующим образом:

  1. Разница между функцией генератора и циклом
  2. Когда каждый должен быть реализован

Ответы [ 2 ]

2 голосов
/ 06 октября 2019

Генератор позволяет создавать элементы «на лету», не сохраняя их все в памяти, прежде чем мы начнем их просматривать. Цикл - это просто способ сделать генератор, или другой итеративный, дать нам один элемент за раз.

Например:

for i in range(10):
    print(i)

Блок for является циклом,и range в основном генератор. range не создает list за 1-10 до начала цикла, оно просто создает генератор, создатель этих элементов. Вы также можете представить range(1000000000000000000), что опять-таки не заняло бы времени на создание (и не заняло бы память), поскольку ни один из элементов не был создан до тех пор, пока он не понадобится.

С другой стороны, наш цикл может также взять один элемент из объектов, которые уже существуют, например list:

for i in [0,1,2,3,4,5,6,7,8,9]:
    print(i)

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

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

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

Подробнее о разнице

РЕДАКТИРОВАТЬ: @Vicrobot правильно, заявив, что range на самом деле не генератор, но в целях объяснения "лени" генераторов это то, что я использовал для простоты

0 голосов
/ 06 октября 2019

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

def my_range(n):
    for i in range(n):
        yield i

range_of_10 = my_range(10)
for i in range_of_ten:
    print(i)

result:

0
1
3
4
5
6
7
8
9

или

>>> range_of_ten = my_range(10)
>>> next(range_of_ten)
0
>>> next(range_of_ten)
1
etc.
>>> next(range_of_ten)
9
>>> next(range_of_ten)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Мне нравится следующий пример, где вы можетезамените двойной цикл в одном цикле следующим образом:

def double_loop(n, m):
    for i in range(n):
        for j in range(m):
            yield i, j


n = double_loop(2, 4)
for i in n:
    print(i)

результат

(0, 0)
(0, 1)
(0, 2)
(0, 3)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
...