I tried using random.randint(0, 100)
, but some numbers were the same. Is there a method/module to create a list unique random numbers?
def getScores():
# open files to read and write
f1 = open("page.txt", "r");
p1 = open("pgRes.txt", "a");
gScores = [];
bScores = [];
yScores = [];
# run 50 tests of 40 random queries to implement "bootstrapping" method
for i in range(50):
# get 40 random queries from the 50
lines = random.sample(f1.readlines(), 40);
This will return a list of 10 numbers selected from the range 0 to 99, without duplicates.
With reference to your specific code example, you probably want to read all the lines from the file once and then select random lines from the saved list in memory. For example:
This way, you only need to actually read from the file once, before your loop. It's much more efficient to do this than to seek back to the start of the file and call
f1.readlines()
again for each loop iteration.Linear Congruential Pseudo-random Number Generator
This problem can be solved with a simple Linear Congruential Generator. This requires constant memory overhead (8 integers) and at most 2*(sequence length) computations.
All other solutions use more memory and more compute! If you only need a few random sequences, this method will be significantly cheaper. For sequences of length
k
, if you want to generate on the order ofk
unique sequences or more, I recommend the solution posed by @Handcraftsman.Code
Usage
The usage of this function "random_range" is the same as for any generator (like "range"). An example:
Sample Results
You can first create a list of numbers from
a
tob
, wherea
andb
are respectively the smallest and greatest numbers in your list, then shuffle it with Fisher-Yates algorithm or using the Python'srandom.shuffle
method.The answer provided here works very well with respect to time as well as memory but a bit more complicated as it uses advanced python constructs such as yield. The simpler answer works well in practice but, the issue with that answer is that it may generate many spurious integers before actually constructing the required set. Try it out with populationSize = 1000, sampleSize = 999. In theory, there is a chance that it doesn't terminate.
The answer below addresses both issues, as it is deterministic and somewhat efficient though currently not as efficient as the other two.
where the functions getElem, percolateUp are as defined below
Finally, the timing on average was about 15ms for a large value of n as shown below,
If you need to sample extremely large numbers, you cannot use
range
because it throws:
Also, if
random.sample
cannot produce the number of items you want due to the range being too smallit throws:
This function resolves both problems:
Usage with extremely large numbers:
Sample result:
Usage where the range is smaller than the number of requested items:
Sample result:
It also works with with negative ranges and steps:
Sample results:
From the CLI in win xp:
In Canada we have the 6/49 Lotto. I just wrap the above code in lotto.bat and run
C:\home\lotto.bat
or justC:\home\lotto
.Because
random.randint
often repeats a number, I useset
withrange(7)
and then shorten it to a length of 6.Occasionally if a number repeats more than 2 times the resulting list length will be less than 6.
EDIT: However,
random.sample(range(6,49),6)
is the correct way to go.