【问题标题】:Randomly capitalize letters in string [duplicate]随机大写字符串中的字母[重复]
【发布时间】:2019-03-27 07:19:03
【问题描述】:

我想将字符串中的每个字母随机大写或小写。我是在 python 中使用字符串的新手,但我认为因为字符串是不可变的,所以我不能执行以下操作:

i =0             
for c in sentence:
    case = random.randint(0,1)
    print("case = ", case)
    if case == 0:
        print("here0")
        sentence[i] = sentence[i].lower()
    else:
        print("here1")
        sentence[i] = sentence[i].upper()
    i += 1
print ("new sentence = ", sentence)

并得到错误:TypeError: 'str' object does not support item assignment

但是我还能怎么做呢?

【问题讨论】:

  • 使用另一个容器,例如list,然后从中创建字符串。或者,逐步创建一个新的 sting
  • 您始终可以创建一个带有随机大写和小写字母的新字符串。

标签: python python-3.x uppercase lowercase


【解决方案1】:

您可以将str.join 与这样的生成器表达式一起使用:

from random import choice
sentence = 'Hello World'
print(''.join(choice((str.upper, str.lower))(c) for c in sentence))

样本输出:

heLlo WORLd

【讨论】:

  • 不,列表理解会更慢,因为它会先将所有项目值具体化以形成一个列表,然后再将列表传递给join,从而导致更多的时间和内存开销。使用生成器表达式,join 方法将能够简单地遍历生成器输出,因为生成器会一一生成项目值。
  • 很好..谢谢你告诉我
  • @U9-Forward 你是对的。 join 需要一个列表,因此首先给它一个列表比给它一个生成器要快。 Authoritative reference.
  • @timgeb 哦,我是对的,哇,现在我知道了 :-)
  • @timgeb 我站在那里纠正。谢谢。
【解决方案2】:

构建一个新字符串。

这是一个对您的原始代码稍作改动的解决方案:

>>> import random
>>> 
>>> def randomcase(s):
...:    result = ''
...:    for c in s:
...:        case = random.randint(0, 1)
...:        if case == 0:
...:            result += c.upper()
...:        else:
...:            result += c.lower()
...:    return result
...:
...:
>>> randomcase('Hello Stackoverflow!')
>>> 'hElLo StaCkoVERFLow!'

edit: 删除了我的oneliners,因为我更喜欢blhsing。

【讨论】:

    【解决方案3】:
    import random
    sentence='quick test'
    print(''.join([char.lower() if random.randint(0,1) else char.upper() \
                       for char in sentence]))
    

    快速测试

    【讨论】:

    • 您可以将您的列表传递给''join()以获得更完整的解决方案
    • 虽然这个答案对我和@blhsing 的答案一样适用,但它的性能有点差。
    【解决方案4】:

    只需将字符串实现更改为列表实现即可。由于字符串是不可变的,因此您无法更改对象内部的值。但是Lists 可以,所以我只更改了您的那部分代码。请注意,有更好的方法可以做到这一点,关注here

    import random
    sentence = "This is a test sentence" # Strings are immutable
    i =0
    new_sentence = [] # Lists are mutable sequences
    for c in sentence:
        case = random.randint(0,1)
        print("case = ", case)
        if case == 0:
            print("here0")
            new_sentence += sentence[i].lower() # append to the list
        else:
            print("here1")
            new_sentence += sentence[i].upper() # append to the list
        i += 1
    print ("new sentence = ", new_sentence)
    
    # to print as string
    new_sent = ''.join(new_sentence)
    print(new_sent)
    

    【讨论】:

      【解决方案5】:

      你可以像下面那样做

      char_list = []            
      for c in sentence:
          ucase = random.randint(0,1)
          print("case = ", case)
          if ucase:
              print("here1")
              char_list.append(c.upper())
          else:
              print("here0")
              char_list.append(c.lower())
      print ("new sentence = ", ''.join(char_list))
      

      【讨论】:

        【解决方案6】:

        不涉及 python 循环的一种方法是将其发送到 numpy 并对其进行矢量化操作。例如:

        import numpy as np
        def randomCapitalize(s):
            s  = np.array(s, 'c').view('u1')
            t  = np.random.randint(0, 2, len(s), 'u1') # Temporary array
            t *= s != 32 # ASCII 32 (i.e. space) should not be lowercased
            t *= 32 # Decrease ASCII by 32 to lowercase
            s -= t
            return s.view('S' + str(len(s)))[0]
        randomCapitalize('hello world jfwojeo jaiofjowejfefjawivj a jofjawoefj')
        

        哪个输出:

        b'HELLO WoRlD jFwoJEO JAioFjOWeJfEfJAWIvJ A JofjaWOefj'
        

        这个解决方案应该相当快,尤其是对于长字符串。这种方法有两个限制:

        • 输入必须完全小写。你可以先试试.lower(),但这在技术上效率很低。

        • 需要特别注意非 a-to-z 字符。在上面的例子中,只处理了空格

        您可以通过替换同时处理更多的特殊字符

        t *= s != 32
        

        # using space, enter, comma, period as example
        t *= np.isin(s, list(map(ord, ' \n,.')), invert=True)
        

        例如:

        s = 'ascii table and description. ascii stands for american standard code for information interchange. computers can only understand numbers, so an ascii code is the numerical representation of a character such as'
        randomCapitalize(s)
        

        哪个输出:

        b'ascII tABLe AnD descRiptIOn. ascii sTaNds for AmEricAN stanDaRD codE FOr InForMAtION iNTeRCHaNge. ComPUtERS can onLY UNdersTand nUMBers, So An asCIi COdE IS tHE nuMERIcaL rEPrEsEnTATion Of a CHaractEr such as'
        

        【讨论】:

        • 嘿,如果有问题,我会修复它。您至少会因为不赞成投票而发表评论吗?
        • 不是反对者,但我认为问题在于将 Numpy 和矢量化之类的东西带入 OP 只需要了解可变容器与不可变容器的情况。
        猜你喜欢
        • 1970-01-01
        • 2021-08-18
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 2011-05-28
        • 2013-02-21
        • 2016-06-06
        相关资源
        最近更新 更多