Вопрос-Ответ

How does a generator comprehension works?

Как работает понимание генератора?

Что делает понимание генератора? Как это работает? Я не смог найти учебник по этому поводу.

Переведено автоматически
Ответ 1

Вы понимаете понимание списков? Если это так, выражение генератора похоже на понимание списка, но вместо того, чтобы находить все интересующие вас элементы и упаковывать их в list , оно ожидает и выдает каждый элемент из выражения, один за другим.

>>> 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
>>>

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

Ответ 2

Понимание генератора - это отложенная версия понимания списка.

Это точно так же, как понимание списка, за исключением того, что он возвращает итератор вместо списка, т. е. объект с методом next(), который выдаст следующий элемент.

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

Ответ 3

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

Допустим, вы хотите сгенерировать список квадратов каждого числа от 1 до 10. Вы можете сделать это на Python:

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

here, range(1,11) generates the list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], but the range function is not a generator before Python 3.0, and therefore the construct I've used is a list comprehension.

If I wanted to create a generator that does the same thing, I could do it like this:

>>> (x**2 for x in xrange(1,11))
<generator object at 0x7f0a79273488>

In Python 3, however, range is a generator, so the outcome depends only on the syntax you use (square brackets or round brackets).

Ответ 4

Generator comprehension is an easy way of creating generators with a certain structure. Lets say you want a generator that outputs one by one all the even numbers in your_list. If you create it by using the function style it would be like this:

def allEvens( L ):
for number in L:
if number % 2 is 0:
yield number

evens = allEvens( yourList )

You could achieve the same result with this generator comprehension expression:

evens = ( number for number in your_list if number % 2 == 0 )

In both cases, when you call next(evens) you get the next even number in your_list.

2024-01-02 17:58 python