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);
You can use Numpy library for quick answer as shown below -
Given code snippet lists down 6 unique numbers between the range of 0 to 5. You can adjust the parameters for your comfort.
Output
It doesn't put any constraints as we see in random.sample as referred here.
Hope this helps a bit.
The solution presented in this answer works, but it could become problematic with memory if the sample size is small, but the population is huge (e.g.
random.sample(insanelyLargeNumber, 10)
).To fix that, I would go with this:
So, I realize this post is 6 years old, but there is another answer with (usually) better algorithmic performance, although less practical with larger overhead.
Other answers include the shuffle method and the 'try until valid' method using sets.
If we're randomly choosing K integers without replacement from the interval 0...N-1, then the shuffle method uses O(N) storage and O(N) operations, which is annoying if we are choosing small K from large N. The set method only uses O(K) storage, but has worst case O(inf) expected O(n*log(n)) for K close to N. (Imagine trying to randomly get the last number out of two allowed answers, having already selected 999998, for k=n-1=10^6).
So the set method is fine for K~1, and the shuffle method is fine for K~N. Both use expected >K RNG calls.
Another way; you can pretend to do the Fisher–Yates shuffle, and for every new random selection, perform a binary search operation on your already-selected elements to find the value that you would get if you were actually storing an array of all the elements you haven't chosen yet.
If your already-selected values are [2,4], and your random number generator spits out 2 in the interval (N - num_already_selected), then you pretend to select out of [0,1,3,5,6,...] by counting the values less than the answer that have already been selected. In this case, your third selected value would be 3. Then, in the next step, if your random number were 2 again, it would map to 5 (in the pretend list [0,1,5,6]), because the (potential index of 5 in the sorted list of already-selected values [2,3,4], which is 3) + 2 = 5.
So store the already-selected values in a balanced binary search tree, store the rank (number of values less than that value) at each node, select a random number R from the range (0... n-(number already chosen)). Then descend the tree as if searching, but your search value is R plus the rank of whatever node you are at. When you reach a leaf node, add the random number to the rank of that node, and insert the sum into the balanced binary tree.
Once you have K elements, read them off the tree into an array and shuffle (if order is important).
This takes O(K) storage, O(K*log(K)) performance, and exactly K randint calls.
Example implementation of random sampling (non-random final ordering but you can O(K) shuffle after), O(k) storage and O(klog^2(k)) performance (not O(klog(k)) because we can't custom-descend balanced binary trees for this implementation):
And to show validity:
If we were doing the fisher-yates shuffle, having already chosen [1,4,6,7,8,9,15,16], with random number 5, our yet-to-be-chosen array would look like [0,2,3,5,10,11,12,...], so element 5 is 11. Thus our binsearch-function should return 11, given 5 and [1,4,6,7,8,9,15,16]:
Inverse of [1,2,3] is [0,4,5,6,7,8,...], the 5th element of which is 8, so:
Inverse of [2,3,5] is [0,1,4,6,...], the 1st element of which is (still) 1, so:
Inverse is [0,6,7,8,...], 3rd element is 8, and:
And to test the overall function:
In practice, though, use the shuffle method for K ~> N/2 and the set method for K ~< N/2.
edit: Here's another way of doing it using recursion! O(k*log(n)) I think.
A very simple function that also solves your problem
You can use the shuffle function from the random module like this:
Note here that the shuffle method doesn't return any list as one may expect, it only shuffle the list passed by reference.