首页 > 解决方案 > 将字符串的每个字母随机大写的代码(代码清理帮助)

问题描述

我是一名初学者,我最近创建了一个函数,它接受一个字符串并将每个字母随机大写。

def rand_upper(string):
    import random
    strList = [l for l in string.lower()] 
    newList = []
    for i in strList:
        j = random.randrange(2)
        if j == 1:
            letter = i.upper()
            newList.append(letter)
        else:
            newList.append(i)
    return "".join(newList)

该代码按我的预期工作,但是有什么方法可以使这个代码更干净吗?我个人认为这很难读。还有其他方法可以压缩代码以使其更具可读性/效率吗?谢谢!

标签: python

解决方案


改为使用,并且只choice调用一次。lowerupper

from random import choice

def rand_upper(string):
    return ''.join(map(choice, zip(string.lower(), string.upper())))

更好的是,正如彼得评论的那样:

def rand_upper(string):
    return ''.join(map(choice, zip(string, string.swapcase())))

另一个,基于Olvin_Roght 的

def rand_upper(string):
    return ''.join([c if getrandbits(1) else c.swapcase() for c in string])

另外两个,以最快的速度混合我们的解决方案:

def rand_upper(string):
    return ''.join([c if getrandbits(1) else d
                    for c, d in zip(string, string.swapcase())])
def rand_upper(string):
    return ''.join([z[getrandbits(1)] for z in zip(string, string.swapcase())])

基准使用string = rand_upper('a' * 1000)

739 μs  797 μs  725 μs  original
764 μs  787 μs  693 μs  original_2
713 μs  691 μs  680 μs  Samwise
699 μs  657 μs  682 μs  theCoder
477 μs  486 μs  490 μs  superb_rain
520 μs  476 μs  489 μs  Peter_Wood
135 μs  131 μs  141 μs  based_on_Olvin_Roght
120 μs  113 μs  121 μs  superb_Peter_Olvin
125 μs  117 μs  118 μs  superb_Peter_Olvin_2

(不包括 Olvin 的原作,因为它是唯一一个使用二次而不是线性时间的,所以与单一大小的比较会产生误导。)

代码:

from timeit import repeat
from random import randrange, choice, getrandbits

def original(string):
    import random
    strList = [l for l in string.lower()] 
    newList = []
    for i in strList:
        j = random.randrange(2)
        if j == 1:
            letter = i.upper()
            newList.append(letter)
        else:
            newList.append(i)
    return "".join(newList)

def original_2(string):
    strList = [l for l in string.lower()] 
    newList = []
    for i in strList:
        j = randrange(2)
        if j == 1:
            letter = i.upper()
            newList.append(letter)
        else:
            newList.append(i)
    return "".join(newList)

def Samwise(string: str) -> str:
    return "".join(
        c.upper() if randrange(2) else c.lower() 
        for c in string
    )

def theCoder(string):
    return ''.join(choice((str.upper, str.lower))(c) for c in string)

def superb_rain(string):
    return ''.join(map(choice, zip(string.lower(), string.upper())))

def Peter_Wood(string):
    return ''.join(map(choice, zip(string, string.swapcase())))

def based_on_Olvin_Roght(string):
    return ''.join([c if getrandbits(1) else c.swapcase() for c in string])

def superb_Peter_Olvin(string):
    return ''.join([c if getrandbits(1) else d for c, d in zip(string, string.swapcase())])

def superb_Peter_Olvin_2(string):
    return ''.join([z[getrandbits(1)] for z in zip(string, string.swapcase())])

funcs = original, original_2, Samwise, theCoder, superb_rain, Peter_Wood, based_on_Olvin_Roght, superb_Peter_Olvin, superb_Peter_Olvin_2

string = original('a' * 1000)
number = 1000

tss = [[] for _ in funcs]
for _ in range(4):
    for func, ts in zip(funcs, tss):
        t = min(repeat(lambda: func(string), number=number)) / number
        ts.append(t)
        print(*('%d μs ' % (1e6 * t) for t in ts[1:]), func.__name__)
    print()

推荐阅读