【问题标题】:Built-in method to Generate Random Strings of Fixed Length From Given Characters从给定字符生成固定长度随机字符串的内置方法
【发布时间】:2012-02-13 16:48:36
【问题描述】:

这就是我的问题:我需要创建一个 50 个字符长的随机字符串,由 1s 和 0s 组成。

我知道如何解决这个问题,甚至有一个解决方案。我还在 SO 上寻找了解决这个问题的各种解决方案,只是为了找回我已经知道的(12 等)。但我真正想要的是 Pythonic 的方式。

目前,我倾向于''.join(( random.choice([0,1]) for i in xrange(50) ))

有没有更 Pythonic 的方式来做到这一点?是否有一个内置的做这样的事情,也许在itertools

【问题讨论】:

    标签: string random python


    【解决方案1】:

    对于 Python2.7 或更高版本:

    In [83]: import random
    
    In [84]: '{:050b}'.format(random.randrange(1<<50))
    Out[84]: '10011110110110000011111000011100101111101001001011'
    

    (在Python2.6中,使用'{0:050b}'而不是'{:050b}'。)


    说明

    string.format 方法可以将整数转换为其二进制字符串表示形式。执行此操作的基本格式代码是'{:b}':

    In [91]: '{:b}'.format(10)
    Out[91]: '1010'
    

    要制作宽度为 50 的字符串,请使用格式代码'{:50b}'

    In [92]: '{:50b}'.format(10)
    Out[92]: '                                              1010'
    

    要使用零填充空格,请使用{:050b}

    In [93]: '{:050b}'.format(10)
    Out[93]: '00000000000000000000000000000000000000000000001010'
    

    syntax for str.format 一开始有点吓人。 这是我的备忘单:

    http://docs.python.org/library/string.html#format-string-syntax
    replacement_field ::= "{" field_name ["!" conversion] [":" format_spec] "}"
    field_name        ::= (identifier|integer)("."attribute_name|"["element_index"]")* 
    attribute_name    ::= identifier
    element_index     ::= integer
    conversion        ::= "r" | "s"
    format_spec       ::= [[fill]align][sign][#][0][width][,][.precision][type]
    fill              ::= <a character other than '}'>
    align             ::= "<" | ">" | "=" | "^"
                          "=" forces the padding to be placed after the sign (if any)
                              but before the digits. (for numeric types)
                          "<" left justification
                          ">" right justification 
                          "^" center justification
    sign              ::= "+" | "-" | " "
                          "+" places a plus/minus sign for all numbers    
                          "-" places a sign only for negative numbers
                          " " places a leading space for positive numbers
    #                     for integers with type b,o,x, tells format to prefix
                          output with 0b, 0o, or 0x.
    0                     enables zero-padding. equivalent to 0= fill align.
    width             ::= integer
    ,                     tells format to use a comma for a thousands separator
    precision         ::= integer
    type              ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" |
                          "o" | "x" | "X" | "%"
        c convert integer to corresponding unicode character
        n uses a locale-aware separator
        % multiplies number by 100, display in 'f' format, with percent sign
    

    【讨论】:

    • 您能补充说明吗?例如,'{:050b}' 做什么?此外,这与@MikeSamuel 的回答具有相同的泛化问题。但这对我来说似乎更蟒蛇(不知道为什么)
    • @inspectorG4dget,{} 表示用format 替换序列的参数; : 表示采用默认(下一个)参数并应用以下格式; 050 表示创建一个带有前导零的 50 位结果; b 表示用二进制编码。
    • @inspectorG4dget,是的,这个答案不可概括。如果这就是你想要的,你就不应该使用二进制数作为例子。
    【解决方案2】:
    # Choose a number in [0, 1L << 50), and format it as binary.
    # The [2:] lops off the prefix "0b"
    bit_str = bin(random.randint(0, (1L << 50) - 1))[2:]
    # We then need to pad to 50 bits.
    fifty_random_bits = '%s%s' % ('0' * (50 - len(bit_str)), bit_str)
    

    【讨论】:

    • 您可以使用random.getrandbits(50) 而不是拨打randint
    • (+1) 当然,这适用于由0s 和1s 组成的字符串,但它不能推广到任意字符集。有没有办法概括这一点?
    • 一个更短的填充方法是:bit_str.rjust(50, "0").
    • @inspectorG4dget,您的任意字符集是基数 2、基数幂 2 还是任何有限基数?我不得不说,这听起来和你问的问题很不一样。
    • @MikeSamuel:很公平。似乎在给定的特异性水平下,这个问题已经得到了回答。我将发布另一个问题来询问普遍性
    【解决方案3】:

    这对我来说看起来很蟒蛇。 如果你想节省字符,你可以去掉括号:

    ''.join( random.choice(['0','1']) for i in xrange(50) )
    

    【讨论】:

      【解决方案4】:
      from random import choice
      from itertools import repeat
      # map or generator expression, take your pick
      "".join( map( choice, repeat( "01", 50)))
      "".join( choice(x) for x in repeat("01", 50))
      

      将输入更改为repeat 以进行泛化。

      【讨论】:

        猜你喜欢
        • 2012-02-13
        • 2015-09-13
        • 1970-01-01
        • 2021-03-15
        • 2019-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-29
        相关资源
        最近更新 更多