问题陈述:给定N
个数字和任意(但非空)set
/ string
/ list
个字符E
,返回长度为N
的随机字符串,由E
中的字符组成。
这种做法最灵活的方式是什么?我可以选择''.join(( random.choice(E) for i in xrange(N) ))
,但我正在寻找一种更好的方法。 random
或itertools
中是否有可以执行此操作的内置函数?
奖励积分如果:
N
和E
PS :这个问题实际上只是我作为一个Python鉴赏家(如果我可以自称),并试图找到优雅和艺术的编写代码的方式。我提到这个的原因是因为它看起来有点像家庭作业,我想向SO社区保证它不是。
答案 0 :(得分:9)
''.join(random.sample(E*N, N))
虽然这不适用于套装,但要考虑它。 但坦率地说,
''.join(random.choice(E) for i in xrange(N))
已经很漂亮 - 它简单,清晰,富有表现力。
需要数小时思考的pythonicness并不是真正的pythonicness。
答案 1 :(得分:4)
您的解决方案看起来已经很不错了,但为了完整起见,这里有一些替代方案:
''.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)
是胜利者,至少对于小E
和N
来说。