Just for comparison's sake, here's a way to implement this using itertools functions, which ends up being faster than the while loop method:
from itertools import count, ifilter, islice
def iter_filt(black_list, lstLen):
return list(islice(ifilter(lambda x: x % 10 not in black_list, count(1)), lstLen))
Usage:
>> print(iter_filt([2,8], 26))
[1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 20, 21, 23, 24, 25, 27, 28, 29, 30, 31, 33]
The function works by starting with count(1), which will generate an infinite series of numbers starting from 1 (1,2,3,4,5,6,...). It then runs that through ifilter, which filters out any results where x % 10 in black_list (as suggested by Barmar). Then islice is used to only take the first lstLen results from the ifiltered count iterator.
Doing it this way is a little faster than the while loop approach:
from itertools import count, islice, ifilter
import timeit
def while_filt(skipNum, lstLength):
lst = []
count_ = 0
while len(lst) < lstLength:
count_ +=1
if count_ % 10 in skipNum:
continue
lst.append(count_)
return lst
def iter_filt(black_list, lstLen):
return list(islice(ifilter(lambda x: x % 10 not in black_list, count(1)), lstLen))
if __name__ == "__main__":
black_list = [2,6]
length = 1000026
print timeit.timeit("while_filt(%s,%s)" % (black_list, length),
setup="from __main__ import while_filt", number=50)
print timeit.timeit("iter_filt(%s,%s)" % (black_list, length),
setup="from __main__ import iter_filt", number=50)
Output:
dan@dantop2:~$ ./funtimes.py
15.1266388893 # while_filt
11.8498108387 # iter_filt