Вы понимаете состав списков? Если это так, выражение генератора похоже на понимание списка, но вместо того, чтобы находить все интересующие вас элементы и упаковывать их в список, оно ожидает и выводит каждый элемент из выражения один за другим.
>>> my_list = [1, 3, 5, 9, 2, 6]
>>> filtered_list = [item for item in my_list if item > 3]
>>> print(filtered_list)
[5, 9, 6]
>>> len(filtered_list)
3>>> # compare to generator expression... >>> filtered_gen = (item for item in my_list if item > 3)
>>> print(filtered_gen) # notice it's a generator object
<generator object <genexpr> at 0x7f2ad75f89e0>
>>> len(filtered_gen) # So technically, it has no length
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'generator' has no len()
>>> # We extract each item out individually. We'll do it manually first.... >>> next(filtered_gen)
5>>> next(filtered_gen)
9>>> next(filtered_gen)
6>>> next(filtered_gen) # Should be all out of items and give an error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> # Yup, the generator is spent. No values for you!... >>> # Let's prove it gives the same results as our list comprehension... >>> filtered_gen = (item for item in my_list if item > 3)
>>> gen_to_list = list(filtered_gen)
>>> print(gen_to_list)
[5, 9, 6]
>>> filtered_list == gen_to_list
True>>>
Поскольку выражение генератора должно выдавать только один элемент за раз, это может привести к значительной экономии использования памяти. Выражения генератора имеют наибольший смысл в сценариях, где вам нужно брать по одному элементу за раз, выполнять много вычислений на основе этого элемента, а затем переходить к следующему элементу. Если вам нужно более одного значения, вы также можете использовать выражение генератора и получать несколько значений за раз. Если вам нужны все значения до того, как ваша программа продолжится, используйте вместо этого понимание списка.
Один вопрос. Я использовал next (gen_name) для получения результата, и он работал в Python 3. Есть ли какой-либо конкретный сценарий, в котором нам нужно использовать __next __ ()?
Анкит Вашиштха
4
@AnkitVashistha Нет, всегда использовать next(...)вместо .__next__()Python 3.
Тодд Сьюэлл,
2
@gotgenes @AnkitVashistha If you need more than one value, you can also use a generator expression and grab a few at a time. Не могли бы вы привести пример такого использования? Спасибо.
LittleZero
21
Генераторное понимание - это ленивая версия понимания списка.
Это похоже на понимание списка, за исключением того, что оно возвращает итератор вместо списка, то есть объект с методом next (), который вернет следующий элемент.
Если вы не знакомы с пониманием списков, смотрите здесь, а генераторы смотрите здесь .
Понимание списка / генератора - это конструкция, которую вы можете использовать для создания нового списка / генератора из существующего.
Допустим, вы хотите создать список квадратов каждого числа от 1 до 10. Вы можете сделать это в Python:
>>> [x**2for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
здесь range(1,11)генерирует список [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], но rangeфункция не является генератором до Python 3.0, и поэтому конструкция, которую я использовал, представляет собой понимание списка.
Если бы я хотел создать генератор, который делает то же самое, я мог бы сделать это так:
>>> (x**2for x in xrange(1,11))
<generator object at 0x7f0a79273488>
Однако в Python 3 rangeесть генератор, поэтому результат зависит только от синтаксиса, который вы используете (квадратные или круглые скобки).
Это не правильно. Является ли внешнее выражение генератором, не имеет ничего общего с тем, является ли внутреннее выражение. Хотя очевидно, что обычно выражение генератора не имеет особого смысла, беря элементы из списка, вы можете это сделать.
Antimony
Можно ли это более четко переписать? Я понимаю, что вы говорите, но, как говорит Сурьма, похоже, что вы говорите что-то еще. (и похоже, что вы говорите неправильно)
Линдон Уайт
4
Понимание генераторов - это простой способ создания генераторов с определенной структурой. Допустим, вам нужен generatorA, который выводит один за другим все четные числа your_list. Если вы создадите его с помощью стиля функции, это будет примерно так:
defallEvens( L ):for number in L:
if number % 2is0:
yield number
evens = allEvens( yourList )
Вы можете добиться того же результата с помощью этого выражения понимания генератора:
evens = ( number for number in your_list if number % 2 == 0 )
В обоих случаях, когда вы звоните, next(evens)вы получаете следующий четный номер your_list.
Понимание генератора - это подход к созданию итераций, что-то вроде курсора, который перемещается по ресурсу. Если вы знаете курсор mysql или курсор mongodb, вы можете знать, что все фактические данные никогда не загружаются в память сразу, а по одному. Курсор перемещается вперед и назад, но в памяти всегда есть один элемент строки / списка.
Короче говоря, используя понимание генераторов, вы можете легко создавать курсоры в Python.
Генераторы аналогичны только спискам, с незначительной разницей в том, что в списках мы получаем все необходимые числа или элементы списка за один раз, а в генераторах необходимые числа выдаются по одному. Поэтому для получения требуемых элементов мы должны использовать цикл for, чтобы получить все необходимые элементы.
#to get all the even numbers in given rangedefallevens(n):for x in range(2,n):
if x%2==0:
yield x
for x in allevens(10)
print(x)
#output2468
Ответы:
Вы понимаете состав списков? Если это так, выражение генератора похоже на понимание списка, но вместо того, чтобы находить все интересующие вас элементы и упаковывать их в список, оно ожидает и выводит каждый элемент из выражения один за другим.
>>> my_list = [1, 3, 5, 9, 2, 6] >>> filtered_list = [item for item in my_list if item > 3] >>> print(filtered_list) [5, 9, 6] >>> len(filtered_list) 3 >>> # compare to generator expression ... >>> filtered_gen = (item for item in my_list if item > 3) >>> print(filtered_gen) # notice it's a generator object <generator object <genexpr> at 0x7f2ad75f89e0> >>> len(filtered_gen) # So technically, it has no length Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'generator' has no len() >>> # We extract each item out individually. We'll do it manually first. ... >>> next(filtered_gen) 5 >>> next(filtered_gen) 9 >>> next(filtered_gen) 6 >>> next(filtered_gen) # Should be all out of items and give an error Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>> # Yup, the generator is spent. No values for you! ... >>> # Let's prove it gives the same results as our list comprehension ... >>> filtered_gen = (item for item in my_list if item > 3) >>> gen_to_list = list(filtered_gen) >>> print(gen_to_list) [5, 9, 6] >>> filtered_list == gen_to_list True >>>
Поскольку выражение генератора должно выдавать только один элемент за раз, это может привести к значительной экономии использования памяти. Выражения генератора имеют наибольший смысл в сценариях, где вам нужно брать по одному элементу за раз, выполнять много вычислений на основе этого элемента, а затем переходить к следующему элементу. Если вам нужно более одного значения, вы также можете использовать выражение генератора и получать несколько значений за раз. Если вам нужны все значения до того, как ваша программа продолжится, используйте вместо этого понимание списка.
источник
next(...)
вместо.__next__()
Python 3.If you need more than one value, you can also use a generator expression and grab a few at a time
. Не могли бы вы привести пример такого использования? Спасибо.Генераторное понимание - это ленивая версия понимания списка.
Это похоже на понимание списка, за исключением того, что оно возвращает итератор вместо списка, то есть объект с методом next (), который вернет следующий элемент.
Если вы не знакомы с пониманием списков, смотрите здесь, а генераторы смотрите здесь .
источник
Понимание списка / генератора - это конструкция, которую вы можете использовать для создания нового списка / генератора из существующего.
Допустим, вы хотите создать список квадратов каждого числа от 1 до 10. Вы можете сделать это в Python:
>>> [x**2 for x in range(1,11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
здесь
range(1,11)
генерирует список[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
, ноrange
функция не является генератором до Python 3.0, и поэтому конструкция, которую я использовал, представляет собой понимание списка.Если бы я хотел создать генератор, который делает то же самое, я мог бы сделать это так:
>>> (x**2 for x in xrange(1,11)) <generator object at 0x7f0a79273488>
Однако в Python 3
range
есть генератор, поэтому результат зависит только от синтаксиса, который вы используете (квадратные или круглые скобки).источник
Понимание генераторов - это простой способ создания генераторов с определенной структурой. Допустим, вам нужен
generator
A, который выводит один за другим все четные числаyour_list
. Если вы создадите его с помощью стиля функции, это будет примерно так:def allEvens( L ): for number in L: if number % 2 is 0: yield number evens = allEvens( yourList )
Вы можете добиться того же результата с помощью этого выражения понимания генератора:
evens = ( number for number in your_list if number % 2 == 0 )
В обоих случаях, когда вы звоните,
next(evens)
вы получаете следующий четный номерyour_list
.источник
Понимание генератора - это подход к созданию итераций, что-то вроде курсора, который перемещается по ресурсу. Если вы знаете курсор mysql или курсор mongodb, вы можете знать, что все фактические данные никогда не загружаются в память сразу, а по одному. Курсор перемещается вперед и назад, но в памяти всегда есть один элемент строки / списка.
Короче говоря, используя понимание генераторов, вы можете легко создавать курсоры в Python.
источник
Другой пример понимания Генератора:
print 'Generator comprehensions' def sq_num(n): for num in (x**2 for x in range(n)): yield num for x in sq_num(10): print x
источник
Генераторы аналогичны только спискам, с незначительной разницей в том, что в списках мы получаем все необходимые числа или элементы списка за один раз, а в генераторах необходимые числа выдаются по одному. Поэтому для получения требуемых элементов мы должны использовать цикл for, чтобы получить все необходимые элементы.
#to get all the even numbers in given range def allevens(n): for x in range(2,n): if x%2==0: yield x for x in allevens(10) print(x) #output 2 4 6 8
источник