Reputation: 1127
I have a sequence defined:
and my current code:
a = [1]
i=1
while a[-1] < 50:
if a[-1] + 5*i < 50:
a.append(a[-1] + 5*i)
i+=1
else:
break
Output:
[1, 6, 16, 31]
can it be done more elegantly and optimally?
Upvotes: 0
Views: 102
Reputation: 106
A really cute one liner:
def seq(n):
return([(1+sum(i for i in range(0,5*j,5))) for j in range(1,n+1)])
print(seq(5))
[1, 6, 16, 31, 51]
Upvotes: 0
Reputation: 56965
I'd write it with a generator:
import itertools
def gen_sequence(maximum):
n = 1
for i in itertools.count(0):
n = n + 5 * i
if n > maximum: break
yield n
if __name__ == "__main__":
print(list(gen_sequence(50))) # => [1, 6, 16, 31]
Or if you don't want to provide an upper limit, you can generate infinitely and let the caller dynamically decide when to quit. This enables the caller to step forward a few iterations and resume later or use itertools.takewhile
to immediately pick up to a limit:
from itertools import count, takewhile
def gen_sequence():
n = 1
for i in count(0):
n = n + 5 * i
yield n
if __name__ == "__main__":
print(list(takewhile(lambda x: x < 50, gen_sequence()))) # => [1, 6, 16, 31]
Whichever way you do it, it's a good idea to put the logic in a function with parameters and check the termination condition once. Ideally come up with a better name for the sequence than gen_sequence
, which is rather ambiguous.
Upvotes: 3
Reputation: 17156
One liners using accumulate
Solution 1: Creates n Terms
from itertools import accumulate
def seq(n):
" Creates n terms of sequence"
return list(accumulate(range(1, n+1), lambda acc, v: acc + 5*(v-1)))
print(seq(5)) # Generate first 5 terms
# Out: [1, 6, 16, 31, 51]
Solution 2--Creates up to Max Value
from itertools import accumulate, takewhile, count
def seq_gen(MAX):
" terms up to value MAX "
return list(takewhile(lambda v: v<=MAX, accumulate(count(start=1), lambda acc, v: acc + 5*(v-1))))
print(seq_gen(50)) # Generate to a maximum value of 50
# Out: [1, 6, 16, 31]
Upvotes: 3
Reputation: 461
Here's the way that I would write it:
def seq(a, n, lst=[]):
a = a + 5 * (n - 1)
n += 1
if a < 50:
lst.append(a)
seq(a, n)
return lst
print(list(seq(1, 1)))
Upvotes: 1
Reputation: 415
This code is just like yours without useless if and break
a = [1]
i=1
while a[-1] + 5*i < 50:
a.append(a[-1] + 5*i)
i+=1
Upvotes: 2
Reputation: 31
I didn't quite understand what exactly the function you are looking for returns, but here's a general implementation in case you are looking to get the number An
def func(n):
if n==1:
return 1
return (func(n-1) + 5*(n-1))
Upvotes: -1