生成一个由 52 个随机字母组成的间隔流,其中每个字母出现两次



好吧,我们可以使用给定的代码片段生成随机字母。

import random
stream_I = ''
for idx in range(0,10):
stream_I = stream_I + ' ' + random.choice('abcdefghijklmnopqrstuvwxyz')
print(stream_I)

但是我想知道如何在两个条件下生成 52 次小写字母 -

  • 它们是随机发生的。
  • 每个小写字母重复两次。

您可以创建一个包含您想要显示的所有字母(即字母表的两倍(的字符串,然后像列表一样打乱这个字符串。

from random import shuffle
import string
orig = 2 * string.ascii_lowercase # or use 2 * 'abcdefghijklmnopqrstuvwxyz'
l = list(orig)
shuffle(l)
print ' '.join(l)  # concatenates every letter in shuffled list with a space in between

只是另一种方式...

>>> random.sample('abcdefghijklmnopqrstuvwxyz' * 2, 52)
['s', 'z', 'c', 'j', 'f', 'k', 'i', 'h', 'f', 'u', 'n', 'u', 'x', 'g', 'v', 'o', 'g', 'x', 'n', 'h', 'q', 'm', 'l', 'k', 'q', 't', 'l', 't', 'z', 'p', 'r', 'd', 'b', 'a', 'p', 'w', 'r', 'e', 'w', 'y', 'v', 'm', 'j', 'c', 'o', 'a', 'd', 's', 'b', 'e', 'i', 'y']

或者,如果您真的想将它们作为字符串连接起来:

>>> ''.join(random.sample('abcdefghijklmnopqrstuvwxyz' * 2, 52))
'idlosakvasfxzuhgerntpzgwivmuopqmybdhkycwtfnlcrjxjbeq'

或者,如果要使用空格打印它们:

>>> print(*random.sample('abcdefghijklmnopqrstuvwxyz' * 2, 52))
t v q n x k g o x m w y i p u t f e h k s b a v r c i j q o l z m l g p d b h y a j r n e w u c d f z s

编辑:另一个,不那么漂亮,但在我的测试中要快得多:

>>> sorted('abcdefghijklmnopqrstuvwxyz' * 2, key=lambda _: random.random())
['p', 'u', 'x', 'm', 'l', 's', 'z', 'p', 'q', 'h', 'g', 'l', 'j', 'r', 'a', 'o', 'o', 'v', 'z', 'r', 'd', 'b', 'c', 'i', 'f', 'c', 'f', 'i', 'v', 'h', 'n', 'w', 'n', 'k', 'u', 'e', 'x', 'g', 'a', 'k', 'w', 'd', 't', 'q', 'm', 'j', 'b', 's', 'e', 't', 'y', 'y']

计时:

>>> from timeit import timeit
>>> timeit("random.sample('abcdefghijklmnopqrstuvwxyz' * 2, 52)",
'import random', number=10**5)
4.6626533971370066
>>> timeit("sorted('abcdefghijklmnopqrstuvwxyz' * 2, key=lambda _: random.random())",
'import random', number=10**5)
1.3866641467300198
>>> timeit("sorted('abcdefghijklmnopqrstuvwxyz' * 2, key=lambda _: random())",
'from random import random', number=10**5)
1.2105088569363005

最后一个版本更合适...上面我只是没有使用它,因为问题的代码确实import random.

看起来sample(和shuffle(的主要时间贡献者可能是随机整数的生成,与随机浮点数相比:

>>> timeit('[randrange(52) for _ in range(52)]', 'from random import randrange', number=10**5)
4.8866115645862465
>>> timeit('[random() for _ in range(52)]', 'from random import random', number=10**5)
0.3504891341253824

从这个消息来源来看,sampleshuffle实际上并没有使用randrange而是使用"私有"_randbelow,但我仍然怀疑这种开销是原因。顺便说一句,至少shuffle可以做得更快。如源代码所示,我们可以给它一个random函数作为参数,然后直接使用它。一些时间:

>>> timeit('shuffle(a)', "from random import shuffle; a = list('abcdefghijklmnopqrstuvwxyz' * 2)", number=10**5)
3.863254275829604
>>> timeit('shuffle(a, random)', "from random import random, shuffle; a = list('abcdefghijklmnopqrstuvwxyz' * 2)", number=10**5)
1.8142924877242876

以下是发布的工作方法之间的一些时间安排:

结果(100,000 次循环(

Stefan_Pochmann: 8.842833116999827
johk95: 8.658055701991543

用于计时的脚本

from timeit import timeit
setup = """
from random import shuffle, sample
from string import ascii_lowercase
"""

methods = {
'Stefan_Pochmann': """
sample(ascii_lowercase * 2, 52)
""",
'johk95': """
orig = 2 * ascii_lowercase
l = list(orig)
shuffle(l)
' '.join(l)
"""
}

for author, method in methods.items():
print('{}: {}'.format(author, timeit(stmt=method, setup=setup, number=100000)))

最新更新