2013-07-03 40 views
2

此代碼基於我收到的優雅答案question,並擴大爲接受最多5個元素的嵌套列表。總體目標是合併在索引位置1處具有重複值的嵌套列表。由於IndexError而無法遍歷嵌套列表

當marker_array中的嵌套列表具有4個元素時,異常通過將抑制IndexError。但代碼未能在最終輸出中的4元素列表之後包含最後一個列表。我的理解是,defaultdict的目的是首先避免IndexErrors。

# Nested list can have 4 or 5 elements per list. Sorted by [1] 
marker_array = [ 
    ['hard','00:01','soft','tall','round'], 
    ['heavy','00:01','light','skinny','bouncy'], 
    ['rock','00:01','feather','tree','ball'], 
    ['fast','00:35','pidgeon','random'], 
    ['turtle','00:40','wet','flat','tail']] 

from collections import defaultdict 
d1= defaultdict(list) 
d2= defaultdict(list) 
d3= defaultdict(list) 
d4= defaultdict(list) 

# Surpress IndexError due to 4 element list. 
# Add + ' ' because ' '.join(d2[x])... create spaces between words. 
try: 
    for pxa in marker_array: 
     d1[pxa[1]].extend(pxa[:1]) 
     d2[pxa[1]].extend(pxa[2] + ' ') 
     d3[pxa[1]].extend(pxa[3] + ' ') 
     d4[pxa[1]].extend(pxa[4] + ' ') 

except IndexError: 
    pass 

# Combine all the pieces. 
res = [[' '.join(d1[x]), 
     x, 
     ''.join(d2[x]), 
     ''.join(d3[x]), 
     ''.join(d4[x])] 
     for x in sorted(d1)] 

# Remove empty elements. 
for p in res: 
    if not p[-1]: 
     p.pop() 

print res 

輸出幾乎是我所需要的:

[['hard heavy rock', '00:01', 'soft light feather ', 'tall skinny tree ', 'round bouncy ball '], ['fast', '00:35', 'pidgeon ', 'random ']] 

這個擴大版無疑失去了一些原本優雅的,由於我的技術水平。在改善這種代碼的任何一般指針大加讚賞,但在重要性排序我的兩個主要問題是:

  1. 我怎樣才能確保[「烏龜」,「00:40」,「溼」, 'flat','tail']嵌套列表不被忽略?
  2. 我能做些什麼來避免像「柔光羽毛」那樣拖尾空白?

回答

3

問題是您的try塊的位置。 IndexError不是由defaultdict引起的,這是因爲您嘗試訪問marker_array的第4行中的pxa[4],該行不存在。

移動你的try /除了裏面的for循環,像這樣:

for pxa in marker_array: 
    try: 
    d1[pxa[1]].extend(pxa[:1]) 
    d2[pxa[1]].extend(pxa[2] + ' ') 
    d3[pxa[1]].extend(pxa[3] + ' ') 
    d4[pxa[1]].extend(pxa[4] + ' ') 
    except IndexError: 
    pass 

輸出現在將包括第4行。

要回答你的第二個問題,你可以通過用strip()rstrip()呼叫周圍的每一個你的各種''.join()電話去除空白加入(例如strip(''.join(d2[x]))

2
  1. 因爲你的try語句開始外for循環,在for循環的異常導致程序去除了塊,而不是返回到循環之後。相反,把試循環內的主要塊之前:

    for pxa in marker_array: 
        try: 
         d1[pxa[1]].extend(pxa[:1]) 
         d2[pxa[1]].extend(pxa[2] + ' ') 
         d3[pxa[1]].extend(pxa[3] + ' ') 
         d4[pxa[1]].extend(pxa[4] + ' ') 
    
        except IndexError: 
         pass 
    

    從技術上講,包括try塊內儘可能少的代碼儘可能最好的做法,因此,如果您確信名單將永遠不會有少於4項目,您可以在擴展d4之前立即將try塊的開始移動到行。

  2. 如果我正確理解你的代碼,你會得到尾隨的空白,因爲你在pxa [4]之後添加了一個空格。當然,刪除d4 [pxa [1]]。extend(pxa [4] +'')中的空格使得它是d4 [pxa [1]]。extend(pxa [4])不會解決您的問題較短的名單。取而代之的是,你不能添加一個空格後PXA [3],而是PXA [4],這樣前添加一個:

     d3[pxa[1]].extend(pxa[3]) 
         d4[pxa[1]].extend(' ' + pxa[4]) 
    

我認爲應該修復它。