Python:对join中的random.choice感到困惑

时间:2011-09-29 15:15:26

标签: python

这是我的代码:

s = 'Hello world'
c = ['a','b','c','d','e','f']
n = ['1','2','3','4','5','6']
l = [random.choice(c),random.choice(n)]
return ''.join('%s%s' % (x, random.choice(l) if random.random() > 0.5 else '') for x in s)

这将输出:

He5lloe w5o5rl5de

但我的目标是这样的代码会产生:

s = 'Hello world'
n = ['1','2','3','4','5','6']
return ''.join('%s%s' % (x, random.choice(n) if random.random() > 0.5 else '') for x in s)

这是:

H4e3l3l6o wo4r3ld

如果有人能够解释为什么两者的反应不同于我的假设,那将会很棒。

对不起,我应该说明我的意图。我想通过连接中for循环的每次迭代从两个列表中随机选择一个元素。相反,我所拥有的是两个元素被选择一次并在所选择的两个元素之间随机选择。

这是我不想要的:

n = [1,2,3,4,5]
s = ['!','-','=','~','|']
l = [random.choice(n), random.choice(s)] # 1,!
# He1l!lo W!or1l!d

这就是我想要的:

n = [1,2,3,4,5] # 1 or 2 or 3... etc.
s = ['!','-','=','~','|'] # ! or - or =... etc.
> code to randomly select a list and a new element from that list
# He4ll-o W!or3l~d

我不确定自己是否有正确的措辞,但希望这是可以理解的,

1 个答案:

答案 0 :(得分:5)

通过执行l = [random.choice(c),random.choice(n)],您将random.choice(l)仅限制为2个可能的字符(每个列表cn中的一个字符)。

请改为尝试:

from random import random, choice
s = 'Hello world'
c = ['a','b','c','d','e','f']
n = ['1','2','3','4','5','6']
L = choice([c, n])  # randomly choose either c or n
return ''.join('%s%s' % (x, choice(L) if random() > 0.5 else '') for x in s)

顺便说一下,假设您想要将插入概率保持在0.5,那么也可以写成:

# for each char, either append an empty string or a random char from list
return ''.join('%s%s' % (x, choice((choice(L), ""))) for x in s)

更新

请注意,上面的答案选择了一个替换列表(cn)并将其用于整个过程。如果您希望能够在替换中使用这两个列表,则可以创建中间列表(L = c + n),也可以在线执行列表选择。

# This is rather convoluted
return ''.join('%s%s' % (x, choice((choice(choice([c, n])), ""))) for x in s)

可替换地,

e = ("", )  # tuple with a single empty element
return ''.join('%s%s' % (x, choice(choice([c, n, e, e]))) for x in s)
  • 选择cn或空列表ee出现两次以保持非空概率为50%。根据需要进行更改)
  • 从所选列表/元组中选择一个随机元素