How to generate a random 4 digit number not starti

2019-03-11 14:36发布

This works almost fine but the number starts with 0 sometimes:

import random
numbers = random.sample(range(10), 4)
print(''.join(map(str, numbers)))

I've found a lot of examples but none of them guarantee that the sequence won't start with 0.

12条回答
2楼-- · 2019-03-11 15:15

This is very similar to the other answers but instead of sample or shuffle you could draw a random integer in the range 1000-9999 until you get one that contains only unique digits:

import random

val = 0  # initial value - so the while loop is entered.
while len(set(str(val))) != 4:  # check if it's duplicate free
    val = random.randint(1000, 9999)

print(val)

As @Claudio pointed out in the comments the range actually only needs to be 1023 - 9876 because the values outside that range contain duplicate digits.

Generally random.randint will be much faster than random.shuffle or random.choice so even if it's more likely one needs to draw multiple times (as pointed out by @karakfa) it's up to 3 times faster than any shuffle, choice approach that also needs to join the single digits.

查看更多
啃猪蹄的小仙女
3楼-- · 2019-03-11 15:15

Here's how I'd do it

while True:
    n = random.randrange(1000, 10000)
    if len(set(str(n))) == 4: # unique digits
        return n

More generally, given a generator, you can use the built-ins filter and next to take the first element that satisfies some test function.

numbers = iter(lambda: random.randrange(1000, 10000), None) # infinite generator
test = lambda n: len(set(str(n))) == 4
return next(filter(test, numbers))
查看更多
劫难
4楼-- · 2019-03-11 15:16

This will allow zeros after the first digit -

numbers = random.sample(range(1,10),1) + random.sample(range(10),3)
查看更多
你好瞎i
5楼-- · 2019-03-11 15:20

I don't know Python so I will post a pseudo-code-ish solution for this specific problem:

  • Create a lookup variable containing a 0-based list of digits:

    lu = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
  • Generate four 0-based random numbers as follows:

    r1 = random number between 0 and 8
    r2 = random number between 0 and 8
    r3 = random number between 0 and 7
    r4 = random number between 0 and 6
    
  • Use the lookup variable to convert random numbers to digits one-by-one. After each lookup, mutate the lookup variable by removing the digit that has been used:

    d1 = lu[r1]
    lu.remove(d1)
    lu.insert(0)
    
    d2 = lu[r2]
    lu.remove(d2)
    
    d3 = lu[r3]
    lu.remove(d3)
    
    d4 = lu[r4]
    lu.remove(d4)
    
  • Print the result:

    print concatenate(d1, d2, d3, d4)
    

It is possible to generalize this idea a little. For example you can create a function that accepts a list (of digits) and a number (desired length of result); the function will return the number and mutate the list by removing used-up digits. Below is a JavaScript implementation of this solution:

function randomCombination(list, length) {
    var i, rand, result = "";
    for (i = 0; i < length; i++) {
        rand = Math.floor(Math.random() * list.length);
        result += list[rand];
        list.splice(rand, 1);
    }
    return result;
}

function desiredNumber() {
    var list = [1, 2, 3, 4, 5, 6, 7, 8, 9],
        result;
    result = randomCombination(list, 1);
    list.push(0);
    result += randomCombination(list, 3);
    return result;
}

var i;
for (i = 0; i < 10; i++) {
    console.log(desiredNumber());
}

查看更多
我想做一个坏孩纸
6楼-- · 2019-03-11 15:23

We generate the first digit in the 1 - 9 range, then take the next 3 from the remaining digits:

import random

# We create a set of digits: {0, 1, .... 9}
digits = set(range(10))
# We generate a random integer, 1 <= first <= 9
first = random.randint(1, 9)
# We remove it from our set, then take a sample of
# 3 distinct elements from the remaining values
last_3 = random.sample(digits - {first}, 3)
print(str(first) + ''.join(map(str, last_3)))

The generated numbers are equiprobable, and we get a valid number in one step.

查看更多
女痞
7楼-- · 2019-03-11 15:24

I do not know Python well, but something like

digits=[1,2,3,4,5,6,7,8,9] <- no zero
random.shuffle(digits)
first=digits[0] <- first digit, obviously will not be zero
digits[0]=0 <- used digit can not occur again, zero can
random.shuffle(digits)
lastthree=digits[0:3] <- last three digits, no repeats, can contain zero, thanks @Dubu

A more useful iteration, actually creating a number:

digits=[1,2,3,4,5,6,7,8,9]   # no zero
random.shuffle(digits)
val=digits[0]                # value so far, not zero for sure
digits[0]=0                  # used digit can not occur again, zero becomes a valid pick
random.shuffle(digits)
for i in range(0,3):
  val=val*10+digits[i]       # update value with further digits
print(val)

After stealing pieces from other solutions, plus applying the tip from @DavidHammen:

val=random.randint(1,9)
digits=[1,2,3,4,5,6,7,8,9]
digits[val-1]=0
for i in random.sample(digits,3):
  val=val*10+i
print(val)
查看更多
登录 后发表回答