2013-11-21 48 views
1

我需要使用遞歸運行數據庫並在結尾處獲取結果列表。函數工作正確(如果打印不是),但我不能返回結果列表。獲得遞歸函數後的數據列表

def find_locks(item, ids): 
    if item.video_id: 
     #print (item.video_id, ids) 
     return (item.video_id, ids) 
    for i in CatalogItem.objects.filter(parent=item): 
     if i.is_lock: 
      find_locks(i, ids.append(i.id)) 
     else: 
      find_locks(i, ids) 

如何獲取列表結果?

+0

你能寫一些輸入和輸出的例子嗎? – itdxer

+0

您只會在'if'分支中返回結果。 – XORcist

+0

你需要爲find_locks賦值或返回find_locks – Leifingson

回答

3

我會使用一個遞歸生成的,而不是建立一個列表:

def find_locks(item, ids): 
    if item.video_id: 
     yield (item.video_id, ids) 
    for i in CatalogItem.objects.filter(parent=item): 
     nxt = ids + [i.id] if i.is_lock else ids 
     for x in find_locks(i, nxt): 
      yield x 

在蟒蛇3.3,您可以使用yield from最後一部分。

+0

我認爲這個變體是最好的,但** id **總是返回爲空列表,真實的數據有ID列表。 – greg

+0

對不起,這是我的錯,所有作品都是正確的!謝謝! – greg

1

您可以將每個結果簡單地存儲在一個列表中,並返回底:

def find_locks(item, ids): 
    if item.video_id: 
     return [(item.video_id, ids)] 
    result = [] 
    for i in CatalogItem.objects.filter(parent=item): 
     if i.is_lock: 
      result.extend(find_locks(i, ids + [i.id])) 
     else: 
      result.extend(find_locks(i, ids)) 
    return result 

請注意,您需要在列表中的其他調用返回的每個項目,以及因爲find_locks期望接收名單作爲返回值。

+0

我知道它也是在gre中的OP中,但'ids.append(i.id)'將返回'None',這可能不是他想到的。 – stranac

+0

@stranac謝謝,現在更新。 –

1

嘗試類似如下:

def find_locks(item, ids): 
    if item.video_id:   
     return [(item.video_id, ids)] 
    res = [] 
    for i in CatalogItem.objects.filter(parent=item): 
     if i.is_lock: 
      res.extend(find_locks(i, ids + [i.id])) 
     else: 
      res.extend(find_locks(i, ids)) 
    return res 

在基本情況下,你與只有一個項目返回列表包括在內。如果它不是基本情況,則創建一個新列表,執行遞歸調用,使用遞歸調用的結果擴展列表並返回此列表。

+1

我知道它也是由greg在OP中,但'ids.append(i.id)'將返回'None',這可能不是他想到的。 – stranac

+0

好點,@stranac!我已經更新了我的答案。 – aga