简体   繁体   English

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

[英]Python: Confused about random.choice within join

Here is my code: 这是我的代码:

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)

This will output: 这将输出:

He5lloe w5o5rl5de

But what I am aiming for is something like this code would produce: 但是我想要的是这样的代码会产生的东西:

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)

Which is: 这是:

H4e3l3l6o wo4r3ld

It would be great if someone could also explain as to why the two are reacting differently than I would have assumed. 如果有人能解释为什么两者的反应与我想象的不同,那就太好了。

Sorry, I should have stated my intentions. 抱歉,我应该说出我的意图。 I would like to randomly select an element from the two lists through each iteration of the for loop within join. 我想通过加入内for循环的每次迭代从两个列表中随机选择一个元素。 Instead what I have is 2 elements being selected once and randomly choosing between the two elements selected. 相反,我所拥有的是一次选择2个元素并在所选择的两个元素之间随机选择。

This is what I don't want: 这是我不想要的:

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

This is what I want: 这就是我要的:

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

Not sure if I have worded myself correctly, but hopefully it is understandable, 不知道我说的话是否正确,但希望可以理解,

By doing l = [random.choice(c),random.choice(n)] you're limiting random.choice(l) to only 2 possible chars (one from each list c and n ). 通过执行l = [random.choice(c),random.choice(n)]您将random.choice(l)限制为仅2个可能的字符(每个cn列表中的一个)。

Try this instead: 尝试以下方法:

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)

As an aside, assuming you want to keep the probability of an insertion at 0.5 , that can also be written as: 顺便说一句,假设您希望将插入的概率保持在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)

Update 更新

Note that the above answer chooses a substitution list ( c or n ) and uses it for the whole process. 请注意,以上答案选择一个替换列表( cn )并将其用于整个过程。 If you want to be able to use both lists in the substitution, you can either create an intermediate list ( L = c + n ), or perform the list selection in-line. 如果希望能够在替换中使用两个列表,则可以创建一个中间列表( L = c + n ),也可以内联执行列表选择。

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

Alternatively, 或者,

e = ("", )  # tuple with a single empty element
return ''.join('%s%s' % (x, choice(choice([c, n, e, e]))) for x in s)
  • Choose between c , n , or empty list e ( e appears twice to keep the non-empty probability at 50%. Change as required) cn或空列表e之间进行选择( e出现两次以将非空概率保持在50%。根据需要进行更改)
  • From the chosen list/tuple, choose a random element 从选择的列表/元组中,选择一个随机元素

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM