【问题标题】:Most Pythonic Way to Generate Random Strings of Fixed Length From Given Characters从给定字符生成固定长度随机字符串的大多数 Pythonic 方法
【发布时间】:2012-02-13 17:11:38
【问题描述】:

这是one of my earlier questions的衍生产品

问题陈述:给定一个数字N和一个任意(但非空)set/string/list字符E,返回一个长度为N的随机字符串E 中的字符。

最pythonic的方式是什么?我可以选择''.join(( random.choice(E) for i in xrange(N) )),但我正在寻找一种更好的方法。 randomitertools 中是否有内置函数可以做到这一点?

奖励积分如果:

  1. 更少的函数调用
  2. 适合一行
  3. 对任何NE 都有更好的通用性
  4. 更好的运行时性能

PS:这个问题实际上只是我作为一名 Python 鉴赏家(如果我可以这样称呼自己的话)并试图找到优雅和艺术的方式来编写代码。我之所以提到这一点是因为它看起来有点像家庭作业,我想向 SO 社区保证它不是。

【问题讨论】:

标签: string random python


【解决方案1】:
''.join(random.sample(E*N, N))

虽然这不适用于集合,但请考虑一下。 但坦率地说,

''.join(random.choice(E) for i in xrange(N))

已经非常 Pythonic 了——它简单、清晰且富有表现力。

需要数小时思考的pythonic并不是真正的pythonic。

【讨论】:

    【解决方案2】:

    您的解决方案已经看起来不错,但为了完整起见,这里有一些替代方案:

    ''.join(map(random.choice, [E]*N))
    

    或者使用 itertools:

    from itertools import repeat
    ''.join(map(random.choice, repeat(E, N)))
    

    如果您使用的是 Python 2.x,itertools.imap() 会比 map() 更高效,因为它不会在内存中创建完整列表。

    这是一些有趣的计时数据(在 Python 2.6 上测试):

    >>> import timeit
    >>> t1 = timeit.Timer("''.join(random.choice('abcdefghijkl') for i in xrange(3))", "import random")
    >>> t2 = timeit.Timer("''.join(map(random.choice, ['abcdefghijkl']*3))", "import random")
    >>> t3 = timeit.Timer("''.join(map(random.choice, repeat('abcdefghijkl', 3)))", "import random; from itertools import repeat")
    >>> t4 = timeit.Timer("''.join(random.sample('abcdefghijkl'*3, 3))", "import random")
    >>> t1.timeit(1000000)   # (random.choice(E) for i in xrange(N))  - OP
    7.0744400024414062
    >>> t2.timeit(1000000)   # map(random.choice, [E]*N)              - F.J
    4.3570120334625244
    >>> t3.timeit(1000000)   # map(random.choice, repeat(E, N))       - F.J
    5.9411048889160156
    >>> t4.timeit(1000000)   # random.sample(E*N, N)                  - DSM
    6.9877378940582275
    

    显然map(random.choice, [E]*N) 是赢家,至少对于小EN

    【讨论】:

    • 有趣。我认为这些数据表明 OP 的解决方案是最好的。这是最明显的,速度是表现最好的速度的两倍。
    猜你喜欢
    • 2012-02-13
    • 1970-01-01
    • 2015-09-13
    • 1970-01-01
    • 2021-03-15
    • 2019-01-05
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    相关资源
    最近更新 更多