Python:关于join中random.choice的困惑
这是我的代码:
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
如果有人能解释一下为什么这两者的反应和我预期的不一样,那就太好了。
抱歉,我应该先说明我的意图。我想在每次循环中随机选择两个列表中的一个元素。而现在的情况是,两个元素被选中一次,然后在这两个选中的元素中随机选择。
这是我不想要的:
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 个回答
5
通过执行 l = [random.choice(c),random.choice(n)]
,你实际上只让 random.choice(l)
有两个可能的字符(一个来自列表 c
,一个来自列表 n
)。
试试下面的方法:
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)
更新
注意,上面的答案是选择了一个替换列表(c
或 n
),并在整个过程中都使用这个列表。如果你想在替换时同时使用两个列表,可以创建一个中间列表(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)
- 在
c
、n
或空列表e
之间选择(e
出现两次是为了保持非空的概率为 50%。可以根据需要进行调整) - 从选择的列表/元组中随机选择一个元素