2011-07-04 97 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