2016-08-24 192 views
0

我需要幫助減少下面的代碼的圈複雜度:的Python:降低圈複雜度

def avg_title_vec(record, lookup): 
    avg_vec = [] 
    word_vectors = [] 
    for tag in record['all_titles']: 
     titles = clean_token(tag).split() 
     for word in titles: 
      if word in lookup.value: 
       word_vectors.append(lookup.value[word]) 
    if len(word_vectors): 
     avg_vec = [ 
      float(val) for val in numpy.mean(
       numpy.array(word_vectors), 
       axis=0)] 

    output = (record['id'], 
       ','.join([str(a) for a in avg_vec])) 
    return output 

例輸入:

record ={'all_titles': ['hello world', 'hi world', 'bye world']} 

lookup.value = {'hello': [0.1, 0.2], 'world': [0.2, 0.3], 'bye': [0.9, -0.1]} 

def clean_token(input_string): 
    return input_string.replace("-", " ").replace("/", " ").replace(
    ":", " ").replace(",", " ").replace(";", " ").replace(
    ".", " ").replace("(", " ").replace(")", " ").lower() 

所以一切都存在於lookup.value的話,我正在考慮它們的矢量形式的平均值。

+1

你介意解釋代碼試圖在第一個地方做什麼? –

+0

增加了一些更多的細節 – futurenext110

+0

我試着從一開始就編碼這個自己,我結束了相同的代碼:) –

回答

0

它可能不算真正的答案,因爲最終圈複雜度不會降低。

這個變種稍微短一些,但是我看不出它可以被推廣到的任何方式。看起來你需要那些if

def avg_title_vec(record, lookup): 
    word_vectors = [lookup.value[word] for tag in record['all_titles'] 
        for word in clean_token(tag).split() if word in lookup.value] 
    if not word_vectors: 
     return (record['id'], None) 
    avg_vec = [float(val) for val in numpy.mean(
       numpy.array(word_vectors), 
       axis=0)] 

    output = (record['id'], 
       ','.join([str(a) for a in avg_vec])) 
    return output 

根據this,你的CC是6,這已經很好了。你可以通過使用幫助功能減少你的功能CC,如

def get_tags(record): 
    return [tag for tag in record['all_titles']] 

def sanitize_and_split_tags(tags): 
    return [word for tag in tags for word in 
      re.sub(r'[\-/:,;\.()]', ' ', tag).lower().split()] 

def get_vectors_words(words): 
    return [lookup.value[word] for word in words if word in lookup.value] 

它會降低平均CC,但整體CC將保持不變或增加。我看不到你如何擺脫那些if檢查單詞是否在lookup.value或檢查我們是否有任何媒介可以使用。