2

I am a beginner in Python currently working through Project Euler's problems (here for those who have not heard about it). I have solved this particular problem, however it leaves me with some questions:

def fibsum():
    result = []
    a, b = 0, 1
    while True:
        a, b = b, a + b
        print b
        if b < 4000000 and b % 2 == 0:
            result.append(b)
        if b > 4000000:
        break
    print sum(result)

fibsum()

When I run this using PowerShell, first it prints out all the numbers I need (although, it goes one over), and then finally prints the sum:

1
2
3
5
8
...
3524578
5702887 <-- This is over 4,000,000. Why is this here?
4613732 <-- This is the answer.
  1. Is there any way that I can have the loop stop iterating before it reaches the first value over 4,000,000?

  2. For the sake of saving space, is there any way that I can have all of the values print out in a list format ([ , , , ]), if I decide to use print?

  3. When I replace print in the original code with yield or return(for the variable b), the program won't print anything out, despite there still being

    print sum(result)

    at the end of the function.

  4. Is there any way that I can make this easier, without having to define result and appending values to it? When the values are returned in a format similar to the actual outcome, sum() doesn't seem to work.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
John Smith
  • 63
  • 2
  • 4

1 Answers1

2

1.Just move the 2nd condition before you print b:

while True:
    a, b = b, a + b  
    if b > 4000000:
        break
    print b
    if b < 4000000 and b % 2 == 0:
        result.append(b)

2.Don't print b in loop, rather print the result once you break out.

3.Well, as for return, it's pretty clear that you return out of function, so the following code in function is not executed and hence your list is not populated.

yield is used to create a generator function, where every execution of your function returns the next value. So, you would have to call your function multiple times, thus adding the yielded value to a list defined outside. And when there is nothing to return, your function will break.

To understand yield keyword usage more clearly, take a look at this post: What does the "yield" keyword do in Python?

You can edit your code to use yield like this (haven't tested it):

def fibsum():
    a, b = 0, 1
    while True:
        a, b = b, a + b
        if b > 4000000:
            break
        yield b

result = []
for val in fibsum():
    if val < 4000000 and val % 2 == 0:
            result.append(val)

print sum(result)

So, in for loop, each call to fibsum() function generates the next value, which you add in the list, based on the condition.

Community
  • 1
  • 1
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525