Every number from 1,2,5,6,9,10... is divisible by 4 with remainder 1 or 2.
>>> ','.join(str(i) for i in xrange(100) if i % 4 in (1,2))
'1,2,5,6,9,10,13,14,...'
Answer from Aleksei astynax Pirogov on Stack OverflowEvery number from 1,2,5,6,9,10... is divisible by 4 with remainder 1 or 2.
>>> ','.join(str(i) for i in xrange(100) if i % 4 in (1,2))
'1,2,5,6,9,10,13,14,...'
>>> ','.join('{},{}'.format(i, i + 1) for i in range(1, 100, 4))
'1,2,5,6,9,10,13,14,17,18,21,22,25,26,29,30,33,34,37,38,41,42,45,46,49,50,53,54,57,58,61,62,65,66,69,70,73,74,77,78,81,82,85,86,89,90,93,94,97,98'
That was a quick and quite dirty solution.
Now, for a solution that is suitable for different kinds of progression problems:
def deltas():
while True:
yield 1
yield 3
def numbers(start, deltas, max):
i = start
while i <= max:
yield i
i += next(deltas)
print(','.join(str(i) for i in numbers(1, deltas(), 100)))
And here are similar ideas implemented using itertools:
from itertools import cycle, takewhile, accumulate, chain
def numbers(start, deltas, max):
deltas = cycle(deltas)
numbers = accumulate(chain([start], deltas))
return takewhile(lambda x: x <= max, numbers)
print(','.join(str(x) for x in numbers(1, [1, 3], 100)))
Trying to be consistent with what you first tried, you could do something like this
def generateNumber(num):
mylist = []
for i in range(num+1):
mylist.append(i)
return mylist
x = generateNumber(10)
but, you could, instead just say,
x = range(10+1) # gives a generator that will make a list
or
x = list(range(10+1)) # if you want a real list
In general though, you should keep this list based on inputting the number 10 so it is [0...9] and not [0...10].
It might help to implement this with the ability to specify a range:
def generateNumber(low, high):
'''returns a list with integers between low and high inclusive
example: generateNumber(2,10) --> [2,3,4,5,6,7,8,9,10]
'''
return range(low, high+1)
This can also be done with the built-in range function:
range(10) --> [0,1,2,3,4,5,6,7,8,9] #note the "off by one"
range(11) --> [0,1,2,3,4,5,6,7,8,9,10]
range(2,11) --> [2,3,4,5,6,7,8,9,10]
More about range: http://docs.python.org/2/library/functions.html#range
If the closed form is available you can use a list comprehension. This has the advantage that all the required memory can be allocated right at the beginning:
seq = [(i + 1)**2 for i in range(1, n+1)]
Repeatedly appending to a list causes internal resizing of the underlying memory and thus involves unnecessary memory allocations and copies.
Without a closed form you can still use a generator:
def gen_seq(n):
a = 0
for i in range(1, n+1):
a += 2*i - 1
yield a
Performance comparison
In [1]: def f1(n):
...: return [(i + 1)**2 for i in range(1, n+1)]
...:
In [2]: def gen_seq(n):
...: a = 0
...: for i in range(1, n+1):
...: a += 2*i - 1
...: yield a
...:
In [3]: def f2(n):
...: return list(gen_seq(n))
...:
In [4]: %timeit f1(100_000)
29.7 ms ± 271 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [5]: %timeit f2(100_000)
16.1 ms ± 176 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
The generator version is almost 2x faster than the list comprehension. This is because the recursive version benefits from the relatively simple operations that are involved. Multiplying an integer by 2 is simply a 1-lshift and adding or subtracting a number is an O(N) operation where N is the number of digits. Multiplying two integers however is O(N*log(N)) and hence takes more time to compute. The recursive version benefits from the already-computed part a_{n-1} which it can reuse at each step.
Specifically in this case, you can just use list(range(1, n)) which is much faster
import time
t = time.time()
print(list(range(1, 1_000_000)))
print(time.time() - t)
Takes less than 0.5 seconds.
[str(i) for i in range(3000, 3100+1)]
This is faster than using map().
Use the range function, then combine with a map(str,)
# list of int
values = list(range(3000, 3101))
print(values) # [3000, 3001, 3002, 3003, 3004 ... 3100]
# list of string representation of int
values = list(map(str, range(3000, 3101)))
print(values) # ['3000', '3001', '3002', '3003',, ... '3100']