2011-07-04 133 views
1

我寫了這個函數。輸入和預期結果在文檔字符串中指示。如何重寫代碼更優雅

def summarize_significance(sign_list): 
    """Summarizes a series of individual significance data in a list of ocurrences. 

    For a group of p.e. 5 measurements and two diferent states, the input data 
    has the form: 

    sign_list = [[-1, 1], 
       [0, 1], 
       [0, 0], 
       [0,-1], 
       [0,-1]] 

    where -1, 0, 1 indicates decrease, no change or increase respectively. 
    The result is a list of 3 items lists indicating how many measurements 
    decrease, do not change or increase (as list items 0,1,2 respectively) for each state: 

    returns: [[1, 4, 0], [2, 1, 2]] 

    """ 
    swaped = numpy.swapaxes(sign_list, 0, 1) 

    summary = [] 
    for row in swaped: 
     mydd = defaultdict(int) 
     for item in row: 
      mydd[item] += 1 
     summary.append([mydd.get(-1, 0), mydd.get(0, 0), mydd.get(1, 0)]) 

    return summary 

我想知道是否有一個更優雅,有效的方式做同樣的事情。一些想法?

+0

有在返回什麼爲例錯誤:它必須是_returns:[1,4,0],[2 **,** 1,2] _ – eyquem

+0

@eyquem吧!我更正了 – joaquin

回答

3

下面是一個使用更少的代碼,並可能更有效,因爲它只是通過sign_list迭代一次,而不調用swapaxes,並且不建一堆的字典。

summary = [[0,0,0] for _ in sign_list[0]] 

for row in sign_list: 
    for index,sign in enumerate(row): 
    summary[index][sign+1] += 1 
return summary 
+0

'index'用於什麼? – joaquin

+0

好的。索引是我們想要增加的總結行,並且符號+ 1是列。這是一個可愛的黑客。 – krasnerocalypse

+0

您不需要使用'range(len(...))',因爲您實際上並不關心這些值是什麼。 –

1

不,只是更復雜的方式。

import itertools 

def summarize_significance(sign_list): 
    res = [] 
    for s in zip(*sign_list): 
    d = dict((x[0], len(list(x[1]))) for x in itertools.groupby(sorted(s))) 
    res.append([d.get(x, 0) for x in (-1, 0, 1)]) 
    return res 
+0

感謝Ignacio,實際上更復雜,但您始終提供了一個學習新內容的機會:-) – joaquin

1

對於初學者來說,你可以這樣做:

swapped = numpy.swapaxes(sign_list, 0, 1) 
for row in swapped: 
    mydd = {-1:0, 0:0, 1:0} 
    for item in row: 
    mydd[item] += 1 
    summary.append([mydd[-1], mydd[0], mydd[1]) 
return summary 
+0

儘管您可以將它保留爲defaultdict(int),因爲int的默認值爲0。 –

+0

是的,這完全是爲了可讀性。 – krasnerocalypse