random.sample python中的“样本大于总体”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20861497/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 21:24:39  来源:igfitidea点击:

"sample larger than population" in random.sample python

pythonstringrandom

提问by Giladiald

creating a simple pass generator for myself, i noticed that if i want my population to be digits only (0-9) which is overall 10 options, if i want my length over 10, it wont use any of the digits more then once and return the "sample larger then population" error.

为自己创建一个简单的通行证生成器,我注意到如果我希望我的人口只有数字(0-9),这是总共 10 个选项,如果我希望我的长度超过 10,它不会使用任何数字超过一次和返回“样本大于总体”错误。

is it possible to maintain the code, but add/reduce code lines so it works? or do i HAVE To use a use random choice?

是否可以维护代码,但添加/减少代码行使其有效?还是我必须使用使用随机选择?

import string
import random

z=int(raw_input("for: \n numbers only choose 1, \n letters only choose 2, \n letters and numbers choose 3, \n for everything choose 4:"))

if z==1:
    x=string.digits
elif z==2:
    x=string.letters
elif z==3:
    x=string.letters+string.digits
elif z==4:
    x=string.letters+string.digits+string.punctuation
else:
    print "die in a fire"

y=int(raw_input("How many passwords would you like?:"))
v=int(raw_input("How long would you like the password to be?:"))

for i in range(y):
    string=""
    for n in random.sample(x,v):
        string+=n
    print string

ty

采纳答案by Martijn Pieters

The purposeof random.sample()is to pick a subsetof the input sequence, randomly, without picking any one element more than once. If your input sequence has no repetitions, neither will your output.

目的random.sample()是选择一个子集的输入序列的,随机,无需拾取任何一种元素多于一次。如果您的输入序列没有重复,您的输出也不会。

You are notlooking for a subset; you want single random choices from the input sequence, repeated a number of times. Elements can be used more than once. Use random.choice()in a loop for this:

不是在寻找一个子集;你想从输入序列中随机选择一个,重复多次。元素可以多次使用。random.choice()为此在循环中使用:

for i in range(y):
    string = ''.join([random.choice(x) for _ in range(v)])
    print string

This creates a string of length v, where characters from xcan be used more than once.

这将创建一个长度为的字符串v,其中的字符x可以多次使用。

Quick demo:

快速演示:

>>> import string
>>> import random
>>> x = string.letters + string.digits + string.punctuation
>>> v = 20
>>> ''.join([random.choice(x) for _ in range(v)])
'Ms>V\0Mf|W@R,#/.P~Rv'
>>> ''.join([random.choice(x) for _ in range(v)])
'TsPnvN&qlm#mBj-!~}3W'
>>> ''.join([random.choice(x) for _ in range(v)])
'{:dfE;VhR:=_~O*,QG<f'

回答by lucas0x7B

@Martijn Pieters is right. But since they state at https://docs.python.org/3.4/library/random.html:

@Martijn Pieters 是对的。但由于他们在https://docs.python.org/3.4/library/random.html 声明

Warning: The pseudo-random generators of this module should not be used for security purposes. Use os.urandom() or SystemRandom if you require a cryptographically secure pseudo-random number generator.

警告:该模块的伪随机生成器不应用于安全目的。如果您需要加密安全的伪随机数生成器,请使用 os.urandom() 或 SystemRandom。

and the purpose of this is for generating passwords, I suggest this approach:

这样做的目的是为了生成密码,我建议使用这种方法:

import string
import random

set = string.letters + string.digits + string.punctuation
length = 20

password = ''.join( [ random.SystemRandom().choice( set) for _ in range( length) ] )

print( password)

Could anybody please confirm that this is more secure?

有人可以确认这更安全吗?

回答by Александр Морковин

Since the python_3.6 you can use random.choises(x, k=v)for your purpose. It returns a k sized list of elements chosen from the population with replacement. If the population is empty, raises IndexError.

从 python_3.6 开始,您可以random.choises(x, k=v)用于您的目的。它返回从带有替换的总体中选择的 ak 大小的元素列表。如果人口为空,则引发 IndexError。