Using sets (and choice()) is a faster solution than comprehending a list. Such as:
from numpy.random import randint from random import choice from typing import Set def my_rand(start: int, end: int, exclude_values: Set[int] = None): if not exclude_values: # in this case, there are no values to exclude so there is no point in filtering out any return randint(start, end) return choice(list(set(range(start, end)).difference(exclude_values)))
As shown via timeit (the statements in these tests are messy and include redundant statements, like if True, but this is to emulate checks that the function above would do):
>>> timeit.timeit(setup="from random import choice", stmt="choice(list(set(range(0, 300)).difference(set({1, 2, 3, 80, 189, 273}) if True else set())))", number=10000) 0.15672149998135865 >>> timeit.timeit(setup="from random import choice", stmt="choice(list(set(range(0, 300)).difference(set({1, 2, 3, 80, 189, 273}) if True else set())))", number=10000) 0.1651422999566421 >>> timeit.timeit(setup="from random import choice", stmt="choice(list(set(range(0, 300)).difference(set({1, 2, 3, 80, 189, 273}) if True else set())))", number=10000) 0.16615699999965727
>>> timeit.timeit(setup="from random import choice", stmt="choice([i for i in range(0, 300) if True and i not in set({1, 2, 3, 80, 189, 273})])", number=10000) 0.8613313999958336 >>> timeit.timeit(setup="from random import choice", stmt="choice([i for i in range(0, 300) if True and i not in set({1, 2, 3, 80, 189, 273})])", number=10000) 0.9154910000506788 >>> timeit.timeit(setup="from random import choice", stmt="choice([i for i in range(0, 300) if True and i not in set({1, 2, 3, 80, 189, 273})])", number=10000) 0.9114390999311581
random.choice()with that