【问题标题】:Organizing strings in recursive functions - python在递归函数中组织字符串 - python
【发布时间】:2017-12-20 10:25:50
【问题描述】:

我试图在一个函数中拆分和组织一个字符串,我的目标是分离小写和大写字符,然后返回一个新的字符串,基本上像这样:

    "lowercasestring" + " " + "uppercasestring". 

重要的是,所有角色都必须按照他们收到但分开的顺序返回。 我的问题是我必须在一个函数中递归地执行此操作(出于教育目的),我很难理解如果没有外部函数调用递归然后修改字符串,这是如何实现的。

    def split_rec(string):
        if string == '':                                                     
            return "-"                                                     #used to seperate late
        elif str.islower(string[0]) or string[0] == "_" or string[0] == ".": #case1
            return string[0] + split_rec(string[1:])
        elif str.isupper(string[0]) or string[0] == " " or string[0] == "|": #case2
            return split_rec(string[1:]) + string[0]
        else:                                                                #discard other
            return split_rec(string[1:])

    def call_split_rec(string):  
    ##Essentially i want to integrate the functionality of this whole function into the recursion
        mystring = split_rec(string)
        left, right = mystring.split("-")
        switch_right = right[::1]
        print(left + " " + switchright)

仅递归就会返回:

    "lowerUPPERcaseCASE" -> "lowercase" + "ESACREPPU"

我在单个函数中解决此问题的最佳尝试是创建 case2:

    elif str.isupper(string[-1]) or string[-1] == " " or string[-1] == "|": #case2
        return split_rec(string[:-1]) + string[-1]

为了正确打印字符串,大写字母将与最后一个字母一起添加。这里的问题是,当第一个字符为大写而最后一个字符为小写时,我显然会卡住。

我花了很多时间试图找到一个好的解决方案,但我无法找到我的帮助。我希望这个问题不是太愚蠢 - 如果是这样,请随意删除它。谢谢!

【问题讨论】:

    标签: python string recursion


    【解决方案1】:

    我不会递归地这样做,但我想你在这里别无选择。 ;)

    在一个函数中执行此操作的简单方法是使用几个额外的参数作为小写和大写字符的临时存储。

    def split_rec(s, lo='', up=''):
        ''' Recursively split s into lower and upper case parts '''
        # Handle the base case: s is the empty string
        if not s: 
            return lo + ' ' + up
    
        #Otherwise, append the leading char of s 
        # to the appropriate destination...
        c = s[0]
        if c.islower():
            lo += c
        else:
            up += c
            # ... and recurse
        return split_rec(s[1:], lo, up)
    
    # Test
    
    print(split_rec("lowerUPPERcaseCASE"))
    

    输出

    lowercase UPPERCASE
    

    我有几个关于你的代码的 cmets。

    使用string 作为变量名不是一个好主意,因为这是标准模块的名称。除非您想导入该模块,否则它不会有任何伤害,但它仍然可能使阅读您的代码的人感到困惑。 string 模块现在并没有得到很多使用,但在 Python 的早期版本中,标准字符串函数就在那里。但是随后str 类型继承了这些函数作为方法,使得旧的string 函数过时了。

    在这一点上,您通常应该将这些 str 方法称为方法,而不是函数。所以不要这样做:

    str.islower(s[0])
    

    相反,做

    s[0].islower()
    

    【讨论】:

    • 感谢您的帮助!简单地向递归函数添加额外的参数是我忽略的那种简单的解决方案。您对我的代码的 cmets 也非常感谢,还有很多像我这样的小东西仍然丢失。
    【解决方案2】:

    这是一种仅使用字符串作为参数的方法:

    def split_rec(s):
        if not '|' in s:
            s = s + '|'
    
        if s.startswith('|'):                                                     
                return s.replace('|', ' ')
    
        elif s[0].islower():
            return s[0] + split_rec(s[1:])
    
        elif s[0].isupper():
            # we move the uppercase first letter to the end
            s = s[1:] +  s[0]
            return split_rec(s)
        else:                                                                
                return split_rec(s[1:])
    
    split_rec('aAbBCD')
    # 'ab ABCD'
    

    想法是:

    • 我们在末尾添加一个标记(我选择了|
    • 如果第一个字符是小写,我们返回它 + 有组织的其余部分
    • 如果是大写,我们把它移到最后,重新组织整个字符串
    • 一旦到达标记,我们就会停下来:当前字符串是标记后跟有组织的大写字母。我们将标记替换为空格并返回。

    【讨论】:

      【解决方案3】:

      最简单的方法是将sorted 与自定义键一起使用:

      >>> ''.join(sorted("lowerUPPERcaseCASE" + " ", key=str.isupper))
      'lowercase UPPERCASE'
      

      这里真的没有理由使用任何递归函数。如果是出于教育目的,您可以尝试找到一个问题,编写递归函数(斐波那契、树解析、归并排序等)实际上是一个好主意。

      正如@PM2Ring 在 cmets 中提到的,这种排序在这里可以正常工作,因为 Python sortedstable:当按大小写排序时,具有相同大小写的字母相对于彼此保持在相同的位置。

      【讨论】:

      • 当然,但这不是递归的。
      • @PM2Ring:在这里编写递归函数的理由是 0。 “如何用锤子将木板切成两半?”的正确答案?是“使用锯子”,而不是“用锤子施加更大的压力”。
      • 是的,即使我明白这个问题非常不适合递归解决方案,我可以使用迭代轻松解决问题。当我确实需要高效时,您提供的解决方案看起来非常好,谢谢。但是就像我说的那样,问题更多是因为我对如何在这种情况下进行递归工作的理解不足,而不是解决实际问题。
      • 使用递归有 1 个原因:这就是 OP 在问题中所说的。 ;) 通常这意味着他们正在做作业,并且他们必须使用递归,因为这是他们目前正在学习的内容。但是当然,OP也有可能是自学的,而不是被老师强迫使用递归。我完全同意,通常人们应该只在 Python 中适合问题域时才使用递归(比如处理递归数据结构); OTOH,在不是自然方法的情况下学习如何使用递归并没有什么坏处。
      • @cmnty BTW,Eric 的解决方案之所以有效,是因为 Python 的排序函数 TimSort稳定的,因此您可以在多个阶段执行排序,并且每个阶段都不会过度干扰前几个阶段的结果。
      【解决方案4】:

      递归辅助函数的另一种表现

      def f(s):
          def lower(s):
              if not s:
                  return ''
              c = s[0] if s[0].islower() else ''
              return c + lower(s[1:])
          def upper(s):
              if not s:
                  return ''
              c = s[0] if s[0].isupper() else ''
              return c + upper(s[1:])
          return lower(s) + ' ' + upper(s)
      

      【讨论】:

        猜你喜欢
        • 2021-09-22
        • 2021-02-14
        • 1970-01-01
        • 1970-01-01
        • 2011-03-26
        • 2015-05-12
        • 2019-05-11
        • 2015-11-27
        • 2023-04-02
        相关资源
        最近更新 更多