【问题标题】:How can I make this Python recursive function return a flat list?如何让这个 Python 递归函数返回一个平面列表?
【发布时间】:2010-10-09 08:11:42
【问题描述】:

看看这个简单的函数

def prime_factors(n):
    for i in range(2,n):
      if n % i == 0:
        return i, prime_factors(n / i)
    return n

这是prime_factors(120)的结果

(2, (2, (2, (3, 5))))

我希望它返回一个扁平元组或列表,而不是嵌套元组。

(2, 2, 2, 3, 5)

有简单的方法吗?

【问题讨论】:

    标签: python recursion


    【解决方案1】:
    def prime_factors(n):
      for i in range(2,n):
        if n % i == 0:
          return [i] + prime_factors(n / i)
      return [n]
    

    【讨论】:

    • 您可以将列表作为参数传递并附加到它,而不是为每个返回值创建一个新列表。如果列表变大,这可能会节省一些空间和时间。
    • 考虑到原始算法,我认为这里的性能并不重要:-)
    • 究竟为什么会节省时间和空间?
    • @Buzzzz -- 附加到列表比将列表合并到副本中便宜。对于长列表,复制成本很高。
    • @FerdinandBeyer 啊,没想到像附加到字符串会触发整个字符串的重新分配(在像 c#/java 中):)
    【解决方案2】:
    def prime_factors(n):
        for i in range(2,n):
            if n % i == 0:
               yield i
               for p in prime_factors(n / i):
                   yield p
               return
        yield n
    

    例子:

    >>> tuple(prime_factors(100))
    (2, 2, 5, 5)
    

    【讨论】:

      【解决方案3】:

      在不改变原有功能的情况下,来自Python Tricks

      def flatten(x):
          """flatten(sequence) -> list
      
          Returns a single, flat list which contains all elements retrieved
          from the sequence and all recursively contained sub-sequences
          (iterables).
      
          Examples:
          >>> [1, 2, [3,4], (5,6)]
          [1, 2, [3, 4], (5, 6)]
          >>> flatten([[[1,2,3], (42,None)], [4,5], [6], 7, MyVector(8,9,10)])
          [1, 2, 3, 42, None, 4, 5, 6, 7, 8, 9, 10]"""
      
          result = []
          for el in x:
              #if isinstance(el, (list, tuple)):
              if hasattr(el, "__iter__") and not isinstance(el, basestring):
                  result.extend(flatten(el))
              else:
                  result.append(el)
          return result
      

      【讨论】:

        【解决方案4】:

        liw.fi 建议在comment:

        您可以将列表作为 参数并附加到它。如果列表变大,这可能会节省一些空间和时间。

        这是 liw.fi 建议的实现。

        def prime_factors(n, factors=None):
            if factors is None:
                factors = []
            for i in range(2,n):
                if n % i == 0:
                    factors.append(i)
                    return prime_factors(n / i, factors)
            factors.append(n)
            return factors
        

        【讨论】:

        • 不过,有个问题。因为 bar=[] 只被初始化一次,所以当你只用一个参数调用你的函数时(至少在 Python 2.x 中),你总是将项目附加到同一个列表对象中。如果 bar 为 None,则使用 bar=None (...):bar = [];而是。
        • 感谢“因素=无”。在我的本地问题中,我做了“resp = []”并且我遇到了几个问题,因为每次调用的数据都在增长,调用后参数不干净。
        【解决方案5】:

        我不知道这有多相关,但这个函数可以帮助您展平深层嵌套列表(使用递归),并且同样可以应用于手头的问题。虽然,它是用软管给雏菊浇水

        def flatten(S):
            if S == []:
                return S
            if isinstance(S[0], list):
                return flatten(S[0]) + flatten(S[1:])
            return S[:1] + flatten(S[1:])
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-04
          • 1970-01-01
          • 1970-01-01
          • 2016-05-27
          • 2012-04-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多