这个基本可以工作,但是有时候数字以0开头:
import random
numbers = random.sample(range(10), 4)
print(''.join(map(str, numbers)))
我找到了很多例子,但没有一个保证序列不会以0
开头。
这个基本可以工作,但是有时候数字以0开头:
import random
numbers = random.sample(range(10), 4)
print(''.join(map(str, numbers)))
我找到了很多例子,但没有一个保证序列不会以0
开头。
我们在1-9范围内生成第一个数字,然后从剩余数字中取接下来的3个数字:
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)))
生成的数字均匀分布,我们可以在一步内获得有效数字。[n for n in range(1000,10000)if len(set(str(n)))== 4]
。 (续) - David Hammen只要循环直到你找到喜欢的东西:
import random
numbers = [0]
while numbers[0] == 0:
numbers = random.sample(range(10), 4)
print(''.join(map(str, numbers)))
这与其他答案非常相似,但不是使用sample
或shuffle
函数,而是在1000-9999的范围内生成随机整数,直到其中的数字都是唯一的为止:
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)
正如评论中@Claudio指出的那样,范围实际上只需要是1023-9876,因为该范围外的值包含重复数字。
通常情况下,random.randint
比random.shuffle
或random.choice
要快得多,因此即使需要多次抽取(如@karakfa所指出的),它也比任何shuffle
、choice
方法快3倍,而后者还需要连接单个数字。
我对Python不是很熟悉,但是大概是这样的:
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
一个更有用的迭代,实际上创建一个数字:
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)
在借鉴其他解决方案的基础上,并采用@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)
random.shuffle
。 - David Hammen拒绝采样法。从10个数字中创建一个4位数字的随机组合,如果不符合条件,则重新采样。
r4=0
while r4 < 1000:
r4=int(''.join(map(str,random.sample(range(10),4))))
注意到这与@Austin Haskings的答案本质上是相同的。
n -> Infinity
(也就是永远)时,lim 10^(-n) = 0
。 - karakfa[修正] 将所有四个数字向左移动一个位置是不正确的。将前导零与固定位置交换也不正确。但是将前导零与九个位置中的任意一个位置进行随机交换是正确的,并且能够获得相等的概率:
""" Solution: randomly shuffle all numbers. If 0 is on the 0th position,
randomly swap it with any of nine positions in the list.
Proof
Lets count probability for 0 to be in position 7. It is equal to probability 1/10
after shuffle, plus probability to be randomly swapped in the 7th position if
0 come to be on the 0th position: (1/10 * 1/9). In total: (1/10 + 1/10 * 1/9).
Lets count probability for 3 to be in position 7. It is equal to probability 1/10
after shuffle, minus probability to be randomly swapped in the 0th position (1/9)
if 0 come to be on the 0th position (1/10) and if 3 come to be on the 7th position
when 0 is on the 0th position (1/9). In total: (1/10 - 1/9 * 1/10 * 1/9).
Total probability of all numbers [0-9] in position 7 is:
9 * (1/10 - 1/9 * 1/10 * 1/9) + (1/10 + 1/10 * 1/9) = 1
Continue to prove in the same way that total probability is equal to
1 for all other positions.
End of proof. """
import random
l = [0,1,2,3,4,5,6,7,8,9]
random.shuffle(l)
if l[0] == 0:
pos = random.choice(range(1, len(l)))
l[0], l[pos] = l[pos], l[0]
print(''.join(map(str, l[0:4])))
1234
和01234
会产生相同的结果,而包含非领导零的数字(例如1023
)只有一种可能性被抽取。 - MSeifertl
;如果 l[0] == 0
,则从范围为1到10的数字中选择一个位置 pos
,交换 l[0]
和 l[pos]
。 - miradulo您可以使用三个数字的全范围,然后在剩下的数字中选择前导数字:
import random
numbers = random.sample(range(0,10), 3)
first_number = random.choice(list(set(range(1,10))-set(numbers)))
print(''.join(map(str, [first_number]+numbers)))
如果需要重复选择(且数字数量合理),另一种方法是使用itertools.permutations
预先计算可能的输出列表,过滤掉前导零的输出,并从中构建一个整数列表:
import itertools,random
l = [int(''.join(map(str,x))) for x in itertools.permutations(range(10),4) if x[0]]
random.choice(l)
0023
。只有一个 0
。 - Jean-François Fabre我不懂Python,因此我将发布一个伪代码般的解决方案:
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)
这个想法可以稍微概括一下。例如,您可以创建一个函数,接受一个数字列表和一个数字(结果的期望长度);该函数将返回数字并通过删除已使用完的数字来改变列表。以下是此解决方案的JavaScript实现:
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());
}
while True:
n = random.randrange(1000, 10000)
if len(set(str(n))) == 4: # unique digits
return n
更一般地说,给定一个生成器,您可以使用内置的filter
和next
函数来获取满足某些测试函数的第一个元素。
numbers = iter(lambda: random.randrange(1000, 10000), None) # infinite generator
test = lambda n: len(set(str(n))) == 4
return next(filter(test, numbers))
next
结合使用编写Python代码的一种Pythonic方式是使用两个嵌套的生成器和next
:
from random import randint
from itertools import count
print(next(i for i in (randint(1023, 9876) for _ in count()) if len(set(str(i))) == 4))
# 8756
这基本上是 @MSeifert的答案 的一行代码版本。
如果您需要许多随机数字,可以投入一些时间和内存来预处理所有可接受的数字:
import random
possible_numbers = [i for i in range(1023, 9877) if len(set(str(i))) == 4]
1023
和9877
被用作边界,因为没有小于1023或大于9876的整数可以有4个唯一的不同数字。
然后,您只需要使用random.choice
进行非常快速的生成:
print(random.choice(possible_numbers))
# 7234
range()
函数中,你可以指定起始值。在你的情况下,起始值可以是1。 - kuro