*Memo:
- My post explains a generator (2).
- My post explains a generator (3).
- My post explains a generator (4).
- My post explains a generator comprehension.
- My post explains an iterator (1).
A generator:
- is the function which has one or more yield statements to return an iterator and whose type is
generator:- A
yieldstatement is a yield or yield from.
- A
- 's iterator can be created by a generator comprehension:
- A generator comprehension is an expression.
- 's iterator cannot be copied.
- can use throw(), close(), send(),
gi_yieldfrom,gi_runningandgi_suspended. - 's
yieldstatement can be assigned to a variable. - 's
yieldstatement cannot be assigned to aforstatement. - terminates if there are no elements to return, if
close()is called or of course if error occurs.
A generator can be created with a function and one or more yield statements and read with next() as shown below:
*Memo:
- __next__() can also be used to read a generator.
- A
yieldstatements is ayieldoryield from. - A
yieldcan return any type of element. - A
yield fromcan only return an iterable.
<yield>:
def gen():
yield 0
yield 1
yield 2
print(gen) # <function func at 0x000001FCD2FF93A0>
print(type(gen)) # <class 'function'>
v = gen()
print(v) # <generator object func at 0x000001FCD3015220>
print(type(v)) # <class 'generator'>
print(next(v)) # 0
print(next(v)) # 1
print(next(v)) # 2
print(next(v)) # StopIteration:
def gen():
yield [0, 1, 2]
yield [3, 4, 5]
v = gen()
print(next(v)) # [0, 1, 2]
print(next(v)) # [3, 4, 5]
print(next(v)) # StopIteration:
<yield from>:
def gen():
yield from [0, 1, 2]
yield from [3, 4, 5]
print(gen) # <function func at 0x000001FCD640B1A0>
print(type(gen)) # <class 'function'>
v = gen()
print(v) # <generator object func at 0x000001FCD661DD80>
print(type(v)) # <class 'generator'>
print(next(v)) # 0
print(next(v)) # 1
print(next(v)) # 2
print(next(v)) # 3
print(next(v)) # 4
print(next(v)) # 5
print(next(v)) # StopIteration:
def gen():
yield from 0
yield from 1
yield from 2
v = gen()
print(next(v))
# TypeError: 'int' object is not iterable
<yield & yield from>:
def gen():
yield [0, 1, 2]
yield from [3, 4, 5]
v = gen()
print(next(v)) # [0, 1, 2]
print(next(v)) # 3
print(next(v)) # 4
print(next(v)) # 5
print(next(v)) # StopIteration:
This is how a generator works as shown below:
*Memo:
-
next()starts or resumes a generator, executes ayieldstatement to return a value and pauses the generator at ayieldstatement or raises StopIteration if a generator is terminated: - A generator is always paused at a
yieldstatement. -
__next__()also does the same things.
<yield>:
def gen():
print('gen() starts.')
yield 'gen() pauses.'
print('gen() resumes.')
yield 'gen() pauses again.'
print('gen() resumes again.')
yield 'gen() terminates.'
v = gen() # `gen()` doesn't start yet.
print(next(v))
# gen() starts.
# gen() pauses.
print(next(v))
# gen() resumes.
# gen() pauses again.
print(next(v))
# gen() resumes again.
# gen() terminates.
print(next(v)) # StopIteration:
<yield from>:
def gen():
print("gen() starts.")
yield from ["gen() pauses.",
"gen() resumes and pauses."]
print("gen() resumes.")
yield from ["gen() pauses.",
"gen() resumes and terminates."]
v = gen() # `gen()` doesn't start yet.
print(next(v))
# gen() starts.
# gen() pauses.
print(next(v))
# gen() resumes and pauses.
print(next(v))
# gen() resumes.
# gen() pauses.
print(next(v))
# gen() resumes and terminates.
print(next(v)) # StopIteration:
This is the generator with a for statement as shown below:
<yield>:
def gen():
for x in [0, 1, 2]:
yield x
v = gen()
print(next(v)) # 0
print(next(v)) # 1
print(next(v)) # 2
print(next(v)) # StopIteration:
def gen():
for x in [[0, 1, 2], [3, 4, 5]]:
yield x
v = gen()
print(next(v)) # [0, 1, 2]
print(next(v)) # [3, 4, 5]
print(next(v)) # StopIteration:
<yield from>:
def gen():
for x in [[0, 1, 2], [3, 4, 5]]:
yield from x
v = gen()
print(next(v)) # 0
print(next(v)) # 1
print(next(v)) # 2
print(next(v)) # 3
print(next(v)) # 4
print(next(v)) # 5
print(next(v)) # StopIteration:
def gen():
for x in [0, 1, 2]:
yield from x
v = gen()
print(next(v))
# TypeError: 'int' object is not iterable
<yield & yield from>:
def gen():
for x in [[0, 1, 2], [3, 4, 5]]:
yield x
yield from x
v = gen()
print(next(v)) # [0, 1, 2]
print(next(v)) # 0
print(next(v)) # 1
print(next(v)) # 2
print(next(v)) # [3, 4, 5]
print(next(v)) # 3
print(next(v)) # 4
print(next(v)) # 5
print(next(v)) # StopIteration:
Top comments (0)