我是一名初级编码员,我最近创建了一个函数,该函数接受一个字符串并随机将每个字母大写。
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)
Run Code Online (Sandbox Code Playgroud)
该代码按我的意图工作,但是有什么方法可以使此代码更清晰吗?我个人认为这很难阅读。有没有其他方法可以压缩代码以使其更具可读性/效率?谢谢!
使用choice代替,lower并且upper只调用一次。
from random import choice
def rand_upper(string):
return ''.join(map(choice, zip(string.lower(), string.upper())))
Run Code Online (Sandbox Code Playgroud)
更好的是,正如彼得评论的那样:
def rand_upper(string):
return ''.join(map(choice, zip(string, string.swapcase())))
Run Code Online (Sandbox Code Playgroud)
另一个,基于Olvin_Roght 的:
def rand_upper(string):
return ''.join([c if getrandbits(1) else c.swapcase() for c in string])
Run Code Online (Sandbox Code Playgroud)
还有两个,混合我们迄今为止最快的解决方案:
def rand_upper(string):
return ''.join([c if getrandbits(1) else d
for c, d in zip(string, string.swapcase())])
Run Code Online (Sandbox Code Playgroud)
def rand_upper(string):
return ''.join([z[getrandbits(1)] for z in zip(string, string.swapcase())])
Run Code Online (Sandbox Code Playgroud)
基准使用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
Run Code Online (Sandbox Code Playgroud)
(不包括 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()
Run Code Online (Sandbox Code Playgroud)
掌握生成器表达式是使代码更短的好方法:
from random import randrange
def rand_upper(string: str) -> str:
return "".join(
c.upper() if randrange(2) else c.lower()
for c in string
)
Run Code Online (Sandbox Code Playgroud)
>>> rand_upper("Sphinx of black quartz, witness my vow!")
'sPhiNx of BlacK qUARTz, wiTnEsS mY VOw!'
Run Code Online (Sandbox Code Playgroud)
一般的技巧是,每当您通过append一次 ing 一个元素来构建列表时,可能有一种方法可以更简单地作为列表理解来完成它,即编写一个生成列表中每个元素的表达式。
如果您实际上没有返回列表,而是将其传递给接受任何可迭代的函数(例如str.join),则可以省略列表部分( )[]并将生成器表达式直接传递给该函数。