Skip to content Skip to sidebar Skip to footer

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)

Solution 1:

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 list e (e appears twice to keep the non-empty probability at 50%. Change as required)
  • From the chosen list/tuple, choose a random element

Post a Comment for "Python: Confused About Random.choice Within Join"