5

I'm try to append text strings randomly so that instead of just having an output like

>>>david

I will end up having something like

>>>DaViD
>>>dAviD

the code i have right now is this

import random
import string

print "Name Year"
text_file = open("names.txt", "r")
for line in text_file:
    print line.strip()+"".join([random.choice(string.digits) for x in range(1, random.randint(1,9))])

and it outports this

>>>JOHN01361

I want that string to be somthing like

>>>jOhN01361
>>>john01361
>>>JOHN01361
>>>JoHn01361

4 Answers 4

7

Well, your specification is actually to randomly uppercase characters, and if you were so inclined, you could achieve that with the following list comprehension:

import random

s = "..."
s = "".join( random.choice([k.upper(), k ]) for k in s )

but there may be nicer ways ...

Sign up to request clarification or add additional context in comments.

2 Comments

k.upper() if random.choice([True, False]) else k is needlessly complicated. Just use random.choice([k.upper(), k]) :)
Cleaner, I agree :) (Changed).
1

you probably want to do something like:

import random

lol = "lol apples"

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

lol =''.join(map(randomupper, lol))

EDIT:

As pointed out by Shawn Chin in the comments, this can be simplified to:

lol = "".join((c.upper(), c)[random() > 0.5] for c in lol)

Very cool and, but slower than using map.


EDIT 2:

running some timer tests, it seems that
"".join( random.choice([k.upper(), k ]) for k in s )
is over 5 times slower than the map method, can anyone confirm this?
Times are:

no map:        5.922078471303955
map:           4.248832001003303
random.choice: 25.282491881882898

4 Comments

Karl's suggestion to use random.choice([k.upper(), k]) is more elegant, in my opinion. If I were to do it your way I'd use a lambda: ''.join(map(lambda c: random.random() > 0.5 and c.upper() or c, lol)).
I try and avoid lambda as much as I can, specially in map because of its poor performance, his solution is defiantly more elegant, but I like having the option of changing the ratio if I prefer to have less / more caps.
Can be written without map or lambda : "".join((c.upper(), c)[random() > 0.5] for c in lol)
@ShawnChin oh wow I thought that statement only worked within lambdas, thanks for the comment, that's a good thing to know.
0

The following might be slightly more efficient than Nook's solution, also it doesn't rely on the text being lower-case to start with:

import random
txt = 'JOHN01361'
''.join(random.choice((x,y)) for x,y in zip(txt.upper(),txt.lower()))

Comments

0

Timing different implementations just for fun:

#!/usr/bin/env python

import random

def f1(s):
    return ''.join(random.choice([x.upper(), x]) for x in s)

def f2(s):
    return ''.join((x.upper(), x)[random.randint(0, 1)] for x in s)

def f3(s):
    def randupper(c):
        return random.random() > 0.5 and c.upper() or c

    return ''.join(map(randupper, s))

def f4(s):
    return ''.join(random.random() > 0.5 and x.upper() or x for x in s)

if __name__ == '__main__':
    import timeit
    timethis = ['f1', 'f2', 'f3', 'f4']
    s = 'habia una vez... truz'
    for f in timethis:
        print '%s: %s' % (f,
                          timeit.repeat('%s(s)' % f, 'from __main__ import %s, s' % f,
                                        repeat=5, number=1000))

This are my times:

f1: [0.12144303321838379, 0.13189697265625, 0.13808107376098633, 0.11335396766662598, 0.11961007118225098]
f2: [0.22459602355957031, 0.23735499382019043, 0.19971895217895508, 0.2097780704498291, 0.22068285942077637]
f3: [0.044358015060424805, 0.051508903503417969, 0.045358896255493164, 0.047426939010620117, 0.042778968811035156]
f4: [0.04383397102355957, 0.039394140243530273, 0.039273977279663086, 0.045912027359008789, 0.039510011672973633]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.