【问题标题】:"sample larger than population" in random.sample pythonrandom.sample python中的“样本大于总体”
【发布时间】:2014-01-18 15:14:03
【问题描述】:

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

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

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

【问题讨论】:

    标签: python string random


    【解决方案1】:

    从 python_3.6 开始,您可以使用random.choices(x, k=v) 来实现您的目的。它返回一个 k 大小的元素列表,该列表是从具有替换的总体中选择的。如果人口为空,则引发 IndexError。

    【讨论】:

      【解决方案2】:

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

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

      而且这样做的目的是生成密码,我建议这种方法:

      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)
      

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

      【讨论】:

      • 或只是 random.choice(chars) 出于好奇,我现在正在运行我的这个程序版本
      【解决方案3】:

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

      不是在寻找子集;您希望输入序列中的单个随机选择,重复多次。元素可以多次使用。为此在循环中使用random.choice()

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

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

      快速演示:

      >>> 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'
      

      【讨论】:

      • 你是个天才!你解决得如此之快,我什至无法选择答案,将在 5 分钟内完成。快速提问(你不必回答我知道这是一个不同的问题,我只是想理解) - 这会使样本无用吗?因为它完全一样,但更多......
      • 不,sample() 有一个不同的目的。想象一下从一副牌中随机挑选 4 张牌。您不能两次选择同一张牌,您需要从牌组中选择 4 张独特的牌。那是一个样本。
      • 您的解决方案是正确的,但我认为根据定义说样本是子集是不正确的。不同之处在于有放回采样和无放回采样(例如,参见Wikipedia)。此外,numpy.random.choice 函数可以选择是否进行替换采样,因此如果您正在处理 numpy 结构,这将很有用。
      • @BrenBarn:random.sample() 的实现非常简单没有替换,因为random.choice() 带有一个循环可以很容易地实现另一个选项。
      • @MartijnPieters:当然,您的编辑让事情变得清晰。我只是说random.sample 所做的与“定义的样本是什么”之间存在差异。
      猜你喜欢
      • 1970-01-01
      • 2016-02-11
      • 2015-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      • 2020-03-31
      相关资源
      最近更新 更多