2014-04-28 134 views
0

我有一個由三個項目組成的子列表。只有第一個和最後一個項目在子列表中很重要,因爲我想根據列表中最後一個項目的頻率更改所有子列表中的最後一個項目。如何根據這些子列表的某些規則和條件更改子列表列表中的項目?

這是名單上有:

lst = [['A','abc','id1'],['A','def','id2'],['A','ghi','id1'],['A','ijk','id1'],['A','lmn','id2'],['B','abc','id3'],['B','def','id3'],['B','ghi','id3'],['B','ijk','id3'],['B','lmn','id'],['C','xyz','id6'],['C','lmn','id6'],['C','aaa','id5']] 

例如,A出現最與ID1代替ID2,所以我想,以取代以A的ID1出現在所有ID2。對於B,id3是最常見的,所以我想用id3替換任何其他的任何實例,這意味着我只想用'id3'替換'id'。對於C,我想用'id6'代替'id5'的實例,因爲'id6'出現在列表最多的位置。

Desired_List = lst = [['A','abc','id1'],['A','def','id1'],['A','ghi','id1'],['A','ijk','id1'],['A','lmn','id1'],['B','abc','id3'],['B','def','id3'],['B','ghi','id3'],['B','ijk','id3'],['B','lmn','id3'],['C','xyz','id6'],['C','lmn','id6'],['C','aaa','id6']] 

我還應該提到,這將在一個非常大的清單上完成,因此需要速度和效率。

+0

此外,您打算如何與desired_list之後呢?這可能會影響它應該採取的形式(最有可能的是,爲了達到你提到的效率,你需要存儲一些比單純的值更有趣的東西)。 – Nacho

回答

1

使用上述ad-hoc要求直接進行數據處理,我可以想出下面的算法。

一次掃描:收集每個鍵的頻率信息(即'A', 'B', 'C'):

def generate_frequency_table(lst): 
    assoc = {}  # e.g. 'A': {'id1': 3, 'id2': 2} 
    for key, unused, val in list: 
     freqs = assoc.get(key, None) 
     if freqs is None: 
      freqs = {} 
      assoc[key] = freqs 
     valfreq = freqs.get(val, None) 
     if valfreq is None: 
      freqs[val] = 1 
     else: 
      freqs[val] = valfreq + 1 
    return assoc 

>>> generate_frequency_table(lst) 
{'A': {'id2': 2, 'id1': 3}, 'C': {'id6': 2, 'id5': 1}, 'B': {'id3': 4, 'id': 1}} 

然後,看看有什麼 '價值' 與每個密鑰關聯(即{'A': 'id1'}):

def generate_max_assoc(assoc): 
    max = {} # e.g. {'A': 'id1'} 
    for key, freqs in assoc.iteritems(): 
     curmax = ('', 0) 
     for val, freq in freqs.iteritems(): 
      if freq > curmax[1]: 
       curmax = (val, freq) 
     max[key] = curmax[0] 
    return max 

>>> maxtable = generate_max_assoc(generate_frequency_table(lst)) 
>>> print maxtable 
{'A': 'id1', 'C': 'id6', 'B': 'id3'} 

最後,遍歷原始列表並使用上表替換值:

>>> newlst = [[key, unused, maxtable[key]] for key, unused, val in lst] 
>>> print newlst 
[['A', 'abc', 'id1'], ['A', 'def', 'id1'], ['A', 'ghi', 'id1'], ['A', 'ijk', 'id1'], ['A', 'lmn', 'id1'], ['B', 'abc', 'id3'], ['B', 'def', 'id3'], ['B', 'ghi', 'id3'], ['B', 'ijk', 'id3'], ['B', 'lmn', 'id3'], ['C', 'xyz', 'id6'], ['C', 'lmn', 'id6'], ['C', 'aaa', 'id6']] 
1

這是相當多由聖誕老人提供了相同的解決方案,但我已將一些步驟合二爲一,因爲我們可以掃描最大價值的同時,我們正在收集頻率:

def fix_by_frequency(triple_list): 
    freq = {} 

    for key, _, value in triple_list: 
     # Get existing data 
     data = freq[key] = \ 
      freq.get(key, {'max_value': value, 'max_count': 1, 'counts': {}}) 

     # Increment the count 
     count = data['counts'][value] = data['counts'].get(value, 0) + 1 

     # Update the most frequently seen 
     if count > data['max_count']: 
      data['max_value'], data['max_count'] = value, count 

    # Use the maximums to map the list 
    return [[key, mid, freq[key]['max_value']] for key, mid, _ in triple_list] 

這一直優化了一些可讀性(我認爲,很好!),而不是原始速度。例如,當你不需要時,你可能不想寫回字典,或者保留一個單獨的最大字典,以防止列表理解中的兩個關鍵字查找。

相關問題