If you can destructively modify names
, just pop
the values instead of copying them. Then they're not there anymore, so you won't be able to repeat.
If you can't destructively modify names
, just do the same to a copy:
tmp = names[:]
result = [tmp.pop(random.randrange(len(tmp))) for _ in range(user_input)]
This does have quadratic performance, since each pop
from the middle of the list has to shift half the list up one notch. But for 150 names, this is unlikely to be a problem. For example, on my laptop, picking 100 values out of 150 names takes 83 microseconds.
If you really aren't allowed to use even randrange, you can write it yourself:
def randrange(x): return randint(0, x-1)