Random Python unique values ​​from two disjoint ranges

The heading contains 100 random unique values ​​from two ranges, or for a more precise definition, there is one range and a subrange that is excluded from the valid values.

The example has a range from 0 to 10000, random 100 numbers that are not in the range from 10 to 20

Requirements:

  • The subband may be at the very beginning or at the very end.
  • Memory overhead to an absolute minimum.
  • Randomization as close as possible to random.shuffle ().

I know random.sample (xrange (0,10000), 100) gives 100 unique values.

Setup I would save three values ​​[start, end, total]

  • start = start of subrange
  • end = end of subrange
  • total = range length

Best I can come up with:

randlist=[]
while len(randlist)<100:
    temp=random.randint(0,total)
    if temp < start or temp > end:
       if temp not in randlist:
           randlist.append(temp)

() - ?

+4
4
randlist = [r + (end - start + 1) * (r >= start) for r in
            random.sample(range(total - end + start), 100)]

/ "":

  • total = 10, start = 2, end = 5
  • 7 : 0, 1, 6, 7, 8, 9, 10
  • ( + ) = (7) 7 0..6 ( )
  • , = 2, + 1 = 4
  • 0, 1, 6, 7, 8, 9, 10.

:

>>> sorted(randlist2(2000000000, 10000000, 1900000000))
[176827, 3235435, 3278133, 3673989, 5148447, 8314140, 8885997, 1900189345, 1902880599,
...
1997494057, 1997538971, 1997854443, 1997907285]

2 , " wikipedia wikipedia english wiki, ".-). OverflowError: Python int too large to convert to C ssize_t. , . , , Python 3.

+3

:

def rand_choice(start, end, amount, istart, iend):
    from random import randint
    all = []
    for i in range(amount):
        randnum = istart
        while randnum in range(istart, iend+1) or randnum in all:
            randnum = randint(start, end)
        all.append(randnum)
    return all

>>> rand_choice(1, 1000, 10, 10, 20)
[30, 798, 427, 229, 943, 386, 749, 925, 520, 877]
>>> rand_choice(1, 1000, 10, 10, 20)
[414, 351, 898, 813, 91, 205, 751, 269, 360, 501]
>>> 
+1

:

def randlist(total, start, end):
    import random
    randset = set()
    while len(randset) < 100:
        temp = random.randint(0, total)
        start <= temp <= end or randset.add(temp)
    return random.sample(randset, 100)
+1

Sequence. , , random.sample.

import collections, random

class range_duo(collections.Sequence):
    def __init__(self, r1, r2):
        self.r1 = r1
        self.r2 = r2
        self.l1 = len(r1)
        self.l2 = len(r2)
        self.total_length = len(r1) + len(r2)

    def __len__(self):
        return self.total_length

    def __getitem__(self, key):
        if key < self.l1:
            return self.r1[key]
        else:
            return self.r2[key-self.l1]


# Solving the example in the original question:
rd = range_duo(range(0, 10), range(20, 10000))
sample = random.sample(rd, 100)
print(sample)

, , random.sample, . Python 2.x range xrange.

+1

All Articles