1. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2012
Posts
46
Rep Power
6

#### Code explanation

Hello. I have this bit of code, but I am not sure what is going on exactly. I know it is taking the multiples of 3 and 5 and adding them, but I am not sure how the code actually accomplishes it.

Code:
sum(i for i in range(1,1000) if (i % 3 == 0) or (i % 5 == 0))
Any explanation would be appreciated
2. It is using a feature of python called list comprehension (google for that term).
Basically, try doing this:
Code:
print( [i for i in range(1,1000) if (i % 3 == 0) or (i % 5 == 0)] )
Basically, this expression:
[i for i in range(1,1000) if (i % 3 == 0) or (i % 5 == 0)]
says:
1. Take i from 1 to 999 (the "for i in range(1,1000)" bit)
2. Check if i is divisible by 3 or 5 (the "if (i % 3 == 0) or (i % 5 == 0)" bit)
3. If so, return i (the leading i in "i for i in ....")
4. Return every i that matches 1..3 in a list.

As a fun aside, try changing the code to:
Code:
print( [i*10 for i in range(1,20) if (i % 3 == 0) or (i % 5 == 0)] )
Note here that the results are i multiplied by 10 (since we have "i * 10" in the beginning).
3. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2012
Posts
46
Rep Power
6
Ooooh, so the leading "i" is basically the return value.

Thank you!!
4. Wonderful. Project Euler #1. Keep going!
5. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2012
Posts
46
Rep Power
6
Code:
def fib(n):
a, b = 1, 2
fib_list = [a]
for i in range(n):
a, b = b, a + b
fib_list.append(a)
return fib_list

print(sum(i for i in fib(31) if i % 2 == 0))
How's this for Euler 2? I feel like there should be a better way since I had to manually type in the range for 'fib(31)' until I noticed that 'a' in 'fib_list' was less than four million.
6. #### A generator might be a better way.

Code:
'''
>>> for f in fib(2000): print('{:4d}'.format(f))
...
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
>>>
'''

def fib(maximum):
a, b = 1, 2
while a < maximum:
yield a
a, b = b, a + b
(I'd accept an argument for <= in place of < )
7. #### "self discovery"

Matrix multiplication can also generate Fibonacci numbers, and it's a quick way to make large ones. numpy doesn't handle arbitrary precision integers; you'll need to write your own matrix multiplication routine. Don Knuth found other formulas for Fibonacci numbers.
Code:
>>> import numpy
>>> F = numpy.asarray(((0,1),(1,1)))
>>> F
array([[0, 1],
[1, 1]])
>>> F.dot(F)
array([[1, 1],
[1, 2]])
>>> F.dot(F).dot(F).dot(F).dot(F)
array([[3, 5],
[5, 8]])
>>> F.dot(F).dot(F).dot(F).dot(F).dot(F).dot(F).dot(F)
array([[13, 21],
[21, 34]])
>>> G = F.dot(F).dot(F).dot(F).dot(F)
>>> G.dot(G)
array([[34, 55],
[55, 89]])
>>>
8. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2012
Posts
46
Rep Power
6
That is so cool. Thank you for showing it
9. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2012
Posts
46
Rep Power
6
Hmmm. I don't quite understand 'yield'.

Is it returning a from the variable below? Or from above? And how does it create a list of numbers?

Any info would be awesome!!!
10. #### in python3...

It could be the doctest you misunderstood. fib didn't make a list.
Code:
>>> fib(3)
<generator object fib at 0x7f5731a627d0>
>>> {'__next__', '__iter__'} . intersection(set(dir(fib)))  # fib looks like a function
set()
>>> {'__next__', '__iter__'} . intersection(set(dir(fib(8888888))))  # calling fib gives an object that supports iteration.
{'__iter__', '__next__'}
Code:
def fib(maximum):
a, b = 1, 2
while a < maximum:
yield a
a, b = b, a + b

# we can make a list of Fibonacci numbers.
print([x for x in fib(22)])  # output is [1, 2, 3, 5, 8, 13, 21]