2016-05-23 53 views
0

我有一個情況我需要返回一個列表中找到的第一個項目,我該如何返回它,當我用遞歸:從遞歸函數返回堆棧變量的最佳方法是什麼?

def get_hostname (ifname): 
    try : 
     # Do something to get hostname 
     return hostname 
    except IOError: 
     return -1 


def get_hostname_r(lst): 
    if not lst: 
     return False 
    if get_hostname(lst[0]) != -1 : 
     print 'Found ', get_hostname(lst[0]) 
     return get_hostname(lst[0]) # DOESNT WORK 
    else : 
     print 'Not found ', get_hostname(lst[0]) 
     get_hostname_r(lst[1:]) 

print 'return = ', get_hostname_r(['eth1','eth2','eth3','eth4','eth5' ]) 

我明白,返回返回到調用堆棧,但蔭尋找最佳實踐而不使用全局變量來獲得價值?

+1

您錯過了'else'情況的'return'關鍵字:'return get_hostname_r(lst [1:])'。另外,讓單個函數返回的值都是相同類型是很好的設計;使用例外來指示錯誤,以及出色的結果。 – chepner

+0

將'get_hostname(lst [0])'提取到一個變量中,以便它只被調用一次。這不會解決你的問題,它只是困擾我,因爲它效率低下。此外,這不是一個很好的遞歸用例,我會建議只用循環來做這件事。 –

回答

2

你可以簡單的返回值,返回值被移交整個遞歸堆棧:

def get_hostname_r(lst): 
    if not lst: 
     return False 
    if get_hostname(lst[0]) != -1 : 
     print 'Found ', get_hostname(lst[0]) 
     return get_hostname(lst[0]) 
    else: 
     print 'Not found ', get_hostname(lst[0]) 
     return get_hostname_r(lst[1:]) 

但更容易閱讀是一個for循環:

def get_hostname_r(interfaces): 
    for interface in interfaces: 
     result = get_hostname(interface) 
     if result != -1: 
      return result 
    return False 
+0

好的。我錯過了.._ r的回報 – Victor

0

首先,如果你不能對IO錯誤做任何事情,不要通過返回-1來掩蓋它(「-1是什麼意思?爲什麼我沒有得到主機名?」)。只要記錄get_hostname可能會引發IOError。

def get_hostname(ifname): 
    # Do stuff that might raise an IOError 
    return hostname 

遞歸版本也是如此。要麼返回一個有效的主機名,要麼引發異常(或者讓未捕獲的異常繼續)。

def get_hostname_r(lst): 
    if not lst: 
     raise IOError("Hostname not found") 

    try: 
     hostname = get_hostname(lst[0]) 
     print >>sys.stderr, 'Found {0}'.format(hostname) 
     return hostname 
    except IOError: 
     print 'Not found with {0}'.format(lst[0]) 
     return get_hostname_r(lst[1:]) 

當然,遞歸不是真正寫這個的最好方法;使用簡單的for循環代替迭代lst

def get_hostname_iter(lst): 
    for ifname in lst: 
     try: 
      return get_hostname(ifname) 
     except IOError: 
      continue 
    raise IOError("Hostname not found") 
相關問題