【问题标题】:Recursive functions on a list of tuples元组列表上的递归函数
【发布时间】:2013-07-26 19:14:08
【问题描述】:

我有以下问题:

首先,我有一个元组列表,如下所示:

[(1,2),(2,3),(4,5),(5,6),(5,7),(5,8),(6,9),(6,10),(7,11),(12,14)]

为了方便起见,假设每个元组中的第一个数字“控制”第二个(对于熟悉依赖解析的人来说,第一个数字代表头的索引,而第二个数字代表依赖的索引) .

现在我要创建的是以int 和上面的列表为参数的函数。该函数必须查找所有将整数参数作为第一个数字的元组并返回第二个数字。然后该函数应该递归地获取这些第二个数字中的每一个,查看它作为第一个数字出现的元组是什么并返回第二个数字。这应该一直持续到无法检索到其他第二个数字为止。

我会用一个例子来更好地解释它: 假设这个函数将数字 5 作为输入。第一个数字为 5 的元组是 (5,6),(5,7),(5,8);作为第一个结果,该函数应取 6,7,8 并将其附加到 list。现在该函数应该考虑 6,7,8 ,查找它们作为第一个数字 ((6,9),(6,10),(7,11)) 出现的元组并返回第二个数字 (9,10,11)。由于 8 在任何元组中都不是第一个数字,因此它的旅程在此阶段结束。返回的最终列表应该是[6,7,8,9,10,11]

我尝试过类似的方法,但它不起作用:

def foo(start_index, lista_tuples,list_to_return=list()):

    indeces=[x[1] for x in lista_tuples if x[0]==start_index]
    list_to_return.extend(indeces)
    for index in indeces:
              foo(index,lista_tuples,list_to_return)
    return list_to_return

但它不起作用。有人能帮我吗?

【问题讨论】:

  • @inspectorG4dget:不是吗? foo(index,lista_tuples,list_to_return)
  • 似乎对我有用。你能添加一个完整的非工作示例吗?
  • 这似乎对我有用:foo(5, [(1,2),(2,3),(4,5),(5,6),(5,7),(5,8),(6,9),(6,10),(7,11),(12,14)]) 返回[6,7,8,9,10,11],就像你说的那样。
  • 天哪!撤回(同时,安排与眼科医生的预约)。
  • 小心mutable default argument,顺便说一句!你真的想在每次调用没有明确提供一个列表时使用相同的列表吗?

标签: python recursion tuples


【解决方案1】:

在您的代码中,您始终会遍历您找到的所有“第二个值”。 这会产生无限递归。 为避免这种情况,请从indeces 中删除list_to_return 中已经存在的所有值:

def foo(start_index, lista_tuples,list_to_return=list()):

    indeces=[x[1] for x in lista_tuples if x[0]==start_index]
    new_values = list(set(indeces) - set(list_to_return))
    list_to_return.extend(indeces)
    for index in new_values:
              foo(index,lista_tuples,list_to_return)
    return list_to_return

双重转换list->set->list有点矫枉过正,不过写下来花了三秒:D

编辑:事实上,你应该实际使用一个集合。这样可以避免重复。

【讨论】:

  • 谢谢!是的,事实上我遇到了这个问题,无法弄清楚是什么原因..
  • 不客气。另外,请遵循 cmets 中的 user2357112 建议,否则您的功能将只能工作一次。 (在我看来,默认参数是 Python 出错的少数几件事之一。)
【解决方案2】:
>>> L =[(1,2),(2,3),(4,5),(5,6),(5,7),(5,8),(6,9),(6,10),(7,11),(12,14)]
>>> def foo(start, L, answer=None):
...     if answer is None:
...         answer = []
...     answer += [i[1] for i in L if i[0]==start]
...     for i in (i[1] for i in L if i[0]==start):
...             foo(i, L, answer)
...     return answer
...
>>> print foo(5, L)
[6, 7, 8, 9, 10, 11]

【讨论】:

    【解决方案3】:

    功能方式

    def worker(n):
        data = []
        for j in [x[1] for x in l if x[0] == n]:
            data += [j] + worker(j)
        return data
    
    print worker(5)
    [6, 9, 10, 7, 11, 8]    
    

    程序方式

    def worker(n, data):
        for j in [x[1] for x in l if x[0] == n]:
            data.append(j)
            worker(j, data)
    
    d = []
    worker(5, d)
    print d
    [6, 9, 10, 7, 11, 8]    
    

    【讨论】:

      【解决方案4】:

      您应该查看这个popular question,它可以解释为什么在您的函数中使用可变默认值可能会导致您出现问题。

      def foo(start_index, lista_tuples):
          return _foo(start_index, lista_tuples, [])
      
      def _foo(start_index, lista_tuples,list_to_return):
      
          indeces=[x[1] for x in lista_tuples if x[0]==start_index]
          list_to_return.extend(indeces)
          for index in indeces:
                    _foo(index,lista_tuples,list_to_return)
          return list_to_return
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-04
        • 2018-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-21
        相关资源
        最近更新 更多