Can you create a python generator to provide values over a range in a random order without repetition?

Question:

I am unsure if this is one of those problems that is impossible or not, in my mind it seems like it should be possible. Edit – We more or less agree it is impossible

Given a range specified by two integers (i.e. n1 ... n2), is it possible to create a python generator that yields a random integer from the range WITHOUT repetitions and WITHOUT loading the list of options into memory (i.e. list(range(n1, n2))).

Expected usage would be something like this:

def random_range_generator(n1, n2):
    ...

gen = random_range_generator(1, 6)

for n in gen:
    print(n)

Output:

4
1
5
3
2
Asked By: Alec Petersen

||

Answers:

How can we shuffle something?

The Idea:

  • generate pairs (random integer, the stuff you want shuffled)
  • sort those pairs by the random integer part
  • output the list of second parts
unsorted = [(random(), x) for x  in range(n1,n2) ]
sorted = sort(unsorted, key = lambda x : x[0])
result = [p[1] for p in sorted]

Note: I haven’t tested this but you get the idea. This is a useful method that can be applied/adapted also to similar problems of reordering one thing, based on the ordering of another list.

Answered By: kutschkem

This is simple enough to do, keeping it in memory. Seems to me impossible otherwise:

import random

def random_range_generator(n1, n2):
    r = list(range(n1, n2))
    random.shuffle(r)
    yield from r

gen = random_range_generator(1, 6)

for n in gen:
    print(n)
Answered By: bvan
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.