Using numpy if memory is not a problem. From the benchmarks on its numbers, the speed seems to be about 10 times faster than the OP code:
import numpy as np def no2(x,d=13): k = len(x)-d t = np.ones(k,dtype=int) xa = np.fromiter(map(int,tuple(x)),dtype=int) for i in range(d): #xrange on python2.x t *= xa[i:k+i] return np.max(t)
To get the numbers that return the maximum, replace np.max(t) with x[np.argmax(t):np.argmax(t)+d] . Example:
no2('123456789101234123412351235324234324234') 1244160
Benchmarking
When testing the string you specified, I find:
#OP approach: %timeit -n 100 no(x) 100 loops, best of 3: 3.49 ms per loop #Kasramvd approach: %timeit -n 100 no3=max((s[i:i+13] for i in range(0, len(s) - 12)), key=lambda x: reduce(mul, map(int, x))) 100 loops, best of 3: 4.22 ms per loop #Andrea approach: %timeit -n 100 no4(x,13) 100 loops, best of 3: 777 µs per loop #numpy approach: %timeit -n 100 no2(x) 100 loops, best of 3: 315 µs per loop
When there is a problem with memory and speed:
When benchmarking using a string 10 ^ 4 times longer (i.e. 10 ^ 7 digits):
#numpy %timeit -n 10 no2(x5) 10 loops, best of 3: 2.2 s per loop #OP code %timeit -n 1 no(x5) 1 loop, best of 3: 37 s per loop #Andrea code %timeit -n 1 no4(x5,13) 1 loop, best of 3: 8.01 s per loop
It is also about 10 times higher than the OP code. Therefore, if the array cannot fit in RAM (but the string can), then numpy will work better.