Python:关于join中random.choice的困惑

0 投票
1 回答
674 浏览
提问于 2025-04-17 03:21

这是我的代码:

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)

更新

注意,上面的答案是选择了一个替换列表(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 或空列表 e 之间选择(e 出现两次是为了保持非空的概率为 50%。可以根据需要进行调整)
  • 从选择的列表/元组中随机选择一个元素

撰写回答