Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

python

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 to do so randomly, but psuedo-random is possible

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
like image 783
Kevin Avatar asked Nov 19 '25 15:11

Kevin


2 Answers

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)
like image 83
bvan Avatar answered Nov 21 '25 04:11

bvan


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.

like image 40
kutschkem Avatar answered Nov 21 '25 04:11

kutschkem