Reputation: 19329
The code below iterates through the numbers ranging between 1 and 5 calling forEachInRangeThisNumberLoopThreeTimes
function passing it a number. The function takes a number and loops it three times appending each iteration to the numbers
list which it returns at the end.
def forEachInRangeThisNumberLoopThreeTimes(number):
numbers = []
for each in range(number):
for i in range(3):
numbers.append(i)
return numbers
result = []
for number in range(1, 5):
print number, forEachInRangeThisNumberLoopThreeTimes(number)
Which prints:
1 [0, 1, 2]
2 [0, 1, 2, 0, 1, 2]
3 [0, 1, 2, 0, 1, 2, 0, 1, 2]
4 [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]
Instead of appending each number to the result
variable I would like to use yield
:
def forEachInRangeThisNumberLoopThreeTimes(number):
for each in range(number):
for i in range(3):
yield i
Now when I execute:
for number in range(1, 5):
result = forEachInRangeThisNumberLoopThreeTimes(number)
the result
is not what I expect:
1 <generator object forEachInRangeThisNumberLoopThreeTimes at 0x104ebfaf0>
2 <generator object forEachInRangeThisNumberLoopThreeTimes at 0x104ebfaf0>
3 <generator object forEachInRangeThisNumberLoopThreeTimes at 0x104ebfaf0>
4 <generator object forEachInRangeThisNumberLoopThreeTimes at 0x104ebfaf0>
Where is the error?
Upvotes: 0
Views: 128
Reputation: 12607
When using yield
inside of a function, it becomes a generator, that's why you are getting these outputs.
I'll use a simpler example to explain how to use generators properly. Let's say we have the following generator:
def example_generator():
yield 1
yield 2
yield 3
Now when I'll call x = example_generator()
, x
will hold a generator not the value 1.
If I want to get the value 1, I would have to
x = example_generator()
first_val = next(example_generator())
Now first_val
has the value 1, calling next()
again, you'll get the value 2. When the generator is exhausted, you'll get a StopIteration
exception
To avoid StopIteration
you could just
for value in example_generator():
print(value)
and in this case you'll get
1
2
3
and the for loop will handle the StopIteration
for you.
If you are looking for getting it as a list
you are basically losing the advantages of using a generator, but it could be done by
list(example_generator())
I hope this was a clear enough explanation so you could understand for yourself how to use generators in python. Happy generating!
Upvotes: 0
Reputation: 309
I think this is what you are looking for:
def forEachInRangeThisNumberLoopThreeTimes(number):
for each in range(number):
for i in range(3):
yield i
result = []
for num in forEachInRangeThisNumberLoopThreeTimes(5):
result.append(num)
or
result = list(forEachInRangeThisNumberLoopThreeTimes(number))
You have to treat your function like an iterable if you use yield
.
Upvotes: 2
Reputation: 11940
yield
designates that a function returns a generator object. It conforms to iterable
interface, so if you want a strict list from it, build the list explicitly:
result = list(forEachInRangeThisNumberLoopThreeTimes(number))
or even
result = [x for x in forEachInRangeThisNumberLoopThreeTimes(number)]
Upvotes: 4