How to randomly uppercase characters in a string?

Viewed 242

I want a way of grab an string variable and randomize which letters are uppercase, like so:

upperRandomizer("HelloWorld") == "HeLLoWORlD"

I've tried this so far:

for p in strVar:
        result = ""
        if random.choice((True, False)):
            result += p.upper()
        else:
            result += p

But the code only spits out the last letter of the string variable. I tried to use the join() method without success. Any help would be appreciated.

4 Answers

Move your result variable outside of the loop. Right now, you are recreating it every time you loop through a character in the list.

result = ""
for p in strVar:
    if random.choice((True, False)):
        result += p.upper()
    else:
        result += p

Here you get a oneliner:

import random

def upperRandomizer(string):
    return "".join([char.upper() if random.randint(0,1) == 0 else char for char in string])

print (upperRandomizer("HelloWorld"))

Output:

HeLLoWorlD
import random

upperRandomizer = lambda s: ''.join(random.choice((str.upper, str.lower))(x) for x in s)

for _ in range(5):
    print(upperRandomizer('HelloWorld'))

Output:

HELlOwORlD
hELlOWoRLd
HELlowORLd
HELLOwOrLd
HeLLoWorlD

At the risk of too much magic, I'd do something like:

from random import choice

def caseRandomizer(text):
    return ''.join(map(choice, zip(text.lower(), text.upper())))

i.e:

  1. get lower and upper case versions of the text
  2. use zip to iterate over them both character by character
  3. map(choice, ...) randomly picks either lower or upper character
  4. ''.join(...) turns the iterator back into a string

Warning, I subsequently realised this doesn't work in general. E.g. 'ß', the lowercase German character called eszett, turns into 'SS' when made uppercase so the upper and lower case versions could go "out of sync".

A version that would work is:

from random import choices

def caseRandomizer(text):
    return ''.join(fn(c) for (fn, c) in zip(choices((str.lower, str.upper), k=len(text)), text))
Related