【问题标题】:Pythons fastest way of randomising case of a stringPython随机化字符串大小写的最快方法
【发布时间】:2012-01-10 19:23:43
【问题描述】:

我想随机化一个字符串的大小写,这就是我所拥有的:

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

我想知道您是否可以使用列表推导来使其更快。 我似乎无法在 randomchoice 中使用 lower() 和 upper() 函数 我试图做类似的事情

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

但我认为那是错误的。类似的事情是可能的吗?

【问题讨论】:

    标签: python string variables random


    【解决方案1】:
    import random
    s = 'this is a lower case string'
    
    ''.join(random.choice((str.upper,str.lower))(x) for x in s)
    

    random.choicestr.upperstr.lower两个函数中随机选择一个。

    然后对于输入字符串s中的每个字母,此函数应用于x

    如果初始字符串的所有字母都是小写的,我会使用这个代码:

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

    因为在小写初始字符串的情况下,初始代码会在一半的字母上使用多余的str.lowercase

    顺便说一下,看看 Michael J. Barber 的另一个答案。 Python 对函数调用收取高额费用。在他的代码中,他只调用了一次str.upper。在我的代码中,str.upper 被调用了大约一半的初始字符串符号。所以还是在内存中创建一个临时的大写字符串,他的代码的时间效率可能会大很多。


    你瞧:

    代码时序对比:https://ideone.com/eLygn

    【讨论】:

    • 为什么要在已经是小写的字符串上调用str.lower()
    • @TimPietzcker 因为初始字符串可能包含大写字母
    • @colonwq:我敢打赌这远非最快的方法。迈克尔的解决方案(修改为处理混合大小写的字符串,这不是您问题的一部分)肯定会更快,尤其是对于较长的字符串。我现在不在家里的电脑上,所以我无法测试它。
    • @ovgolovin 虽然我认为这里的清晰度比速度更重要,但您能否尝试一下 Tim 的建议,将 random.choice 引入本地命名空间?而且我想为了完整性,如果我们完全想放弃可读性以支持速度,''.join(numpy.where(numpy.random.randint(2, size=len(caps)), list(caps), list(lowers))) 值得检查。
    • @MichaelJ.Barber 我已经尝试过random.choice。但我没有将random.choice 放入本地命名空间。我会在几分钟后更新测试代码。
    【解决方案2】:

    试试这个:

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

    这应该优于您的版本,因为它对upper 的调用次数要少得多,而且更重要的是,它避免了您在带有循环的版本中使用的 O(N^2) 连续追加。

    修改问题后,您需要同时创建小写和大写版本:

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

    正如 Tim Pietzcker 在 cmets 中所建议的那样,我使用 random.choicezip 调用创建的元组中选择字母。

    由于问题已更改为更加关注速度,因此最快的方法可能是使用 Numpy:

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

    【讨论】:

    • +1,但random.choice(x) for x in zip(...) 看起来更好 IMO。
    • 是的,我没有提到混合大小写,抱歉。这看起来更快,谢谢。更新了我的问题。
    • 我在答案中添加了时间比较。 @TimPietzcker
    • 使用random.choice(x) 代替x[random.randint(0,1)] 可使代码速度提高2 倍。这是为什么呢?
    • @TimPietzcker 是的,我想它会更好看。我会添加它,并更新混合大小写的可能性。
    猜你喜欢
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 2014-05-04
    • 2015-02-20
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多