As an exercise to try to understand generator functions I am trying to write a function that simulates long division and returns the number one digit at a time. I have written this function and it doesn't seem to work. However if I step through it line by line in the shell it does exactly what I want it to do so I'm not sure what to do going forward. I've read through posts on the internet about generator functions here:
and from what I understand I just replace the return statement with a yield statement. Is this not the case? Can anybody please tell me what I am doing wrong? Any help is appreciated.
def decimals(number):
"""
Takes a numnber and generates the digits of 1/n.
"""
divisor = number
dividend = 1
while dividend % divisor != 0:
#Floor division is the // operator
quotient = divisor // dividend
remainder = dividend % divisor
temp = quotient * divisor
if remainder != 0 :
temp = quotient * divisor
if temp > dividend:
dividend = dividend * 10
dividend = dividend - temp
else:
dividend = dividend - temp
yield quotient
def main():
gen = decimals(4)
print(next(gen))
if __name__ == "__main__":
main()
解决方案
Your main problem is that you output only a single value from the generator: next(gen). To output the whole generator, make a list from it's values: print(list(decimals(4))), or print it value by value:
for digit in decimals(4):
print(digit)
To deal with endless generators (e.g., from a decimals(3) call), you can for example take only a limited amount of values from it with itertools.islice:
from itertools import islice
for digit in islice(decimals(3), 10):
print(digit)
Also, I think there is something wrong with your algorithm. It doesn't seem to produce the correct results. I think, it should look something like this:
def decimals(number):
"""
Takes a number and generates the digits of 1/n.
"""
divisor = number
dividend = 1
remainder = 1
while remainder:
#Floor division is the // operator
quotient = dividend // divisor
remainder = dividend % divisor
if remainder < divisor:
dividend = remainder * 10
else:
dividend = remainder
yield quotient
As a side note, this code may still be made shorter. For example:
def decimals(number):
dividend = 1
while dividend:
yield dividend // number
dividend = dividend % number * 10