4

Is there a more efficient / smarter way of randomizing the uppercasing of letters in a string ? Like this:

input_string = "this is my input string"
for i in range(10):
    output_string = ""
    for letter in input_string.lower():
        if (random.randint(0,100))%2 == 0:
            output_string += letter
        else:
            output_string += letter.upper()
    print(output_string)

Output:

thiS iS MY iNPUt strInG
tHiS IS My iNPut STRInG
THiS IS mY Input sTRINg
This IS my INput STRING
ThIS is my INpUt strIng
tHIs is My INpuT STRInG
tHIs IS MY inPUt striNg
THis is my inPUT sTRiNg
thiS IS mY iNPUT strIng
THiS is MY inpUT sTRing
Chris_Rands
  • 38,994
  • 14
  • 83
  • 119
François M.
  • 4,027
  • 11
  • 30
  • 81
  • 2
    `''.join(c.upper() if random() > 0.5 else c for c in input_string)` – Maroun Aug 07 '17 at 13:04
  • 1
    @MarounMaroun I'm using `timeit` on the four ways (including mine) and your way seems to beat everyone by a large margin. (Couldn't get the `map` way to work though) – François M. Aug 07 '17 at 13:24
  • 1
    For a fair test you should do `''.join(c.upper() if random() > 0.5 else c for c in input_string.lower())`, but checking the implementation actually I'm not surprised `random.choice()` is slower (but more readable). You could also try `''.join(lst[random.getrandbits(1)](c) for c in s)`. Also, should it be `>=`? @MarounMaroun relevant question: https://stackoverflow.com/questions/6824681/get-a-random-boolean-in-python – Chris_Rands Aug 07 '17 at 13:40

2 Answers2

9

You could use random.choice(), picking from str.upper and str.lower:

>>> from random import choice

>>> s = "this is my input string"
>>> lst = [str.upper, str.lower]

>>> ''.join(choice(lst)(c) for c in s)
'thiS IS MY iNpuT strIng'

>>> [''.join(choice(lst)(c) for c in s) for i in range(3)]
['thiS IS my INput stRInG', 'tHiS is MY iNPuT sTRinG', 'thiS IS my InpUT sTRiNg']
Chris_Rands
  • 38,994
  • 14
  • 83
  • 119
1

you could use a map and apply a random factor with the string to do it like this:

import random

StringToRandomize = "Test String"

def randomupperfactor(c):
   if random.random() > 0.5:
      return c.upper()
   else:
      return c.lower()

StringToRandomize =''.join(map(randomupperfactor, StringToRandomize))
Maroun
  • 94,125
  • 30
  • 188
  • 241
Louis-Roch Tessier
  • 822
  • 1
  • 13
  • 25
  • 1
    @MarounMaroun I did not downvote, the approach is fine, but I think an `else` clause is missing. Also the variable names should ideally conform to PEP8 and not be capitalized – Chris_Rands Aug 07 '17 at 13:27