【问题标题】:Swapping letter casing in Python在 Python 中交换字母大小写
【发布时间】:2017-11-22 21:55:27
【问题描述】:

一直在尝试从 Java 过渡到 Python,但我在编写遍历字符串的循环时遇到了困难。
如您所见,我尝试访问每个索引以检查其大小写。如果该字母是大写字母,则我们将其小写,反之亦然。
如果我已经对该特定索引进行更改,我不确定为什么它会返回未更改的字符串

def swap_case(s):

    for x in range(len(s)):
        if s[x].isupper():
            s[x].lower() 
        if s[x].islower():
            s[x].upper()

    return s

【问题讨论】:

  • 字符串是不可变的。 s[x].lower() 返回一个新字符串,你必须对它做点什么。
  • 如果 s 是一个字符串,那么你可以这样做 s.swapcase()
  • 另外,由于缺少 elif,您的两个条件将相互覆盖
  • 你没有保存结果,也没有打电话给upper
  • s 是字符串还是列表?问题说“遍历列表”,然后说“返回未更改的字符串”

标签: python case-sensitive


【解决方案1】:

如果 s 是一个字符串,您可以执行以下操作:

def swap_case(s):
    return s.swapcase()

话虽如此,我认为如果您正在做的只是创建一个函数,那么您不需要创建一个函数。您可以只在字符串上调用 .swapcase() 而不是将其传递给函数。

【讨论】:

    【解决方案2】:

    在 Python 中,字符串是不可变的。因此,您可以使用.join 的列表推导:

    def swap_case(s):
       return ''.join([i.lower() if i.isupper() else i.upper() for i in s])
    

    【讨论】:

    • 字符串是不可变的,不能赋值给s[x]
    • @Barmar 正确,但是,OP 提到他正在迭代一个列表,而不是一个字符串。
    • 您可以删除 [...] 并改用生成器推导式,速度应该可以忽略不计。
    • nit:我不会将i 用于字符串中的字符。 i 只不过是我脑海中的一个索引。我更喜欢cch。 (我提到主要是因为当我浏览这个答案时,我想“嘿,你不能小写索引!”)
    • @TemporalWolf 一般是可以的,但是在join 的情况下,它仍然需要将传递的生成器格式化为列表,因此传递列表实际上更有效。
    【解决方案3】:

    对于递归解决方案:

    def swap_case(s):
        if not s:  # empty string
            return s
        head, tail = s[0], s[1:]
        if head.isupper():
            return head.lower() + swap_case(tail)
        else:
            return head.upper() + swap_case(tail)
    

    这在 Python 中的性能并不理想(通常在底层实现递归很差),但对于合理大小的字符串来说,这并不是那么糟糕。

    【讨论】:

      【解决方案4】:

      正如 cmets 所提到的,s[x].lower() 返回一个新字符串,由于字符串是不可变的,因此无法对其进行分配。所以你需要积累一个新的字符串。

      def swap_case(s):
          s0 = ""
          for x in range(len(s)):
              if s[x].isupper():
                  s0 += s[x].lower() 
              elif s[x].islower():
                  s0 += s[x].upper()
          return s0
      

      您也可以使用 lambda 对其进行迭代,这样会更简洁。

      def swap_case(s):
          s0 = map(lambda x: x.lower() if x.isupper() else x.upper(), s)
          return ''.join(s0)
      

      【讨论】:

        【解决方案5】:

        在 python 中,你不需要循环像for x in range(len(s)) 这样的字符串。相反,python 可以使用for char in message 更简洁。此外,if 子句看起来应该跟在elifelse 之后(对于非字母字符)。下面的代码适用于短消息,因为+= 每次都重新复制字符串,因为它是不可变类型。如果这会影响程序的速度,请考虑改用str.join()

        def swap_case(message):
            swapped_message = ''
            for char in message:
                if char.isupper():
                    swapped_message += char.lower()
                elif char.islower():
                    swapped_message += char.upper()
                else:
                    swapped_message += char
            return swapped_message
        

        【讨论】:

        • 仅代码的答案并不理想。请查看How to Answer,然后查看edit 你的答案,包括为什么它不能像OP 尝试的那样工作如何解决它
        【解决方案6】:

        从您的代码中查看这两条语句:

        s[x].lower()
        s[x].upper()
        

        s[x]不是这个(如你所想):

        +------+------+-----+------+-----+-------------+
        | s[0] | s[1] | ... | s[x] | ... | s[len(s)-1] |
        +------+------+-----+------+-----+-------------+
                              ^^^^
        

        new 1 个字符的字符串仅包含原始字符串 s 中的 xth 字符:

        +------+------+-----+------+-----+-------------+
        | s[0] | s[1] | ... | s[x] | ... | s[len(s)-1] |
        +------+------+-----+------+-----+-------------+
        
                           copy of s[x] 
                     (another place in the memory):
                            +------+
                            |      |
                            +------+
                              ^^^^
        

        因为不允许改变字符串中的字符

        所以您更改了 那个 1 字符字符串 的大小写,保持原始字符串 s 不变。


        注意:

        s = "apple"
        s = "orange"
        

        完全没问题 - 第二条语句没有改变 "apple" 变成"orange" 但它创建了新字符串 "orange"other放置在内存中,然后s标记这个新位置(...原来是字符串“apple”的标签)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-02-04
          • 1970-01-01
          • 2022-01-16
          • 2015-07-28
          • 1970-01-01
          • 2020-07-19
          • 2015-06-13
          • 2014-01-11
          相关资源
          最近更新 更多