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. Instead what I have is 2 elements being selected once and randomly choosing between the two elements selected.
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!开发者_JAVA百科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
).
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:
# 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. 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.
# 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 liste
(e
appears twice to keep the non-empty probability at 50%. Change as required) - From the chosen list/tuple, choose a random element
精彩评论