简体   繁体   中英

Pythons fastest way of randomising case of a string

I want to randomise the case of a string, heres what I have:

word="This is a MixeD cAse stRing"
word_cap=''
for x in word:
        if random.randint(0,1):
                word_cap += x.upper()
        else:
                word_cap += x.lower()
        word = word_cap

print word

Im wondering if you could use list comprehension to make it faster. I couldnt seem to use the lower() and upper() functions in randomchoice i tried to do something like

''.join(randomchoice(x.upper(),x.lower()) for x in word)

but i think thats wrong. something like that though is possible?

import random
s = 'this is a lower case string'

''.join(random.choice((str.upper,str.lower))(x) for x in s)

random.choice randomly selects one from two functions str.upper , str.lower .

Then this function is applied to x for each letter in the input string s .

If initial string has all the letters in lowercase, that I would use this code:

''.join(x.upper() if random.randint(0,1) else x for x in s)

because the initial code would use redundant str.lowercase on half of the letters in the case of lowercase initial string.

By the way, look at the other answer by Michael J. Barber. Python have hefty charges for function calls. In his code he calls str.upper only once. In my code str.upper is called for about half the symbols of the initial string. So still a temporary upper-cased string is created in memory, the time efficiency of his code may be much greater.


Lo and behold:

Code timing comparisons: https://ideone.com/eLygn

Try this:

word="this is a lower case string"
caps = word.upper()
''.join(x[random.randint(0,1)] for x in zip(word, caps))

This should outperform your version because it makes many fewer calls to upper and because, more importantly, it avoids the O(N^2) successive appends you used in the version with the loops.

With the modification to the question, you'll need to create both the lowercase and uppercase versions:

word="This is a MixeD cAse stRing"
caps = word.upper()
lowers = word.lower()
''.join(random.choice(x) for x in zip(caps, lowers))

As suggested by Tim Pietzcker in the comments, I've used random.choice to select the letters from the tuples created by the zip call.

Since the question has been changed to focus more on speed, the fastest approach is likely to be using Numpy:

''.join(numpy.where(numpy.random.randint(2, size=len(caps)), list(caps), list(lowers)))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM