2016-12-01 86 views
0

這個問題是微不足道的,但我無法做到這一點。Python過濾字典中的一個鍵的唯一值,並創建另一個過濾的字典

我有這個初始字典:

d = {'res': [1.1, 2.2, 1.2, 4.5, 1.5, 3.4], 'sp': [1, 1, 2, 3, 4, 4], 'obs': [1, 2, 3, 4, 5, 6]} 

我想採取sp鍵的每個值,並在一個新的字典的關鍵,其中,對於每一個獨特的價值我有另一個字典的改造它一致的其他關鍵值。

最終的輸出應該解釋更好的問題:

new_dict = {1: {'res': [1.1, 2.2], 'obs': [1, 2]}, 2: {'res': [1.2], 'obs': [3]}, 3: {'res': [4.5], 'obs': [4]}, 4: {'res': [1.5, 3.4], 'obs': [5, 6]}} 

所以這個字典的鍵是原始字典的sp關鍵的獨特價值。

由於球員

回答

4
d = {'res': [1.1, 2.2, 1.2, 4.5, 1.5, 3.4], 'sp': [1, 1, 2, 3, 4, 4], 'obs': [1, 2, 3, 4, 5, 6]} 

鑑於輸入:

r = {} 
for i, v in enumerate(d['sp']): 
    r.setdefault(v, {'res':[],'obs':[]}) 
    r[v]['res'].append(d['res'][i]) 
    r[v]['obs'].append(d['obs'][i]) 

這導致:

>>> r 
{1: {'res': [1.1, 2.2], 'obs': [1, 2]}, 2: {'res': [1.2], 'obs': [3]}, 3: {'res': [4.5], 'obs': [4]}, 4: {'res': [1.5, 3.4], 'obs': [5, 6]}} 

爲了擴展用於任意數量的參數的第一解決方案是簡單:

r = {} 
keys = set(d) - set(['sp']) 
for i, v in enumerate(d['sp']): 
    if v not in r: 
     r[v] = dict((k, []) for k in keys) 

    for k in keys: 
     r[v][k].append(d[k][i]) 

這會導致同樣的結果。

使用if v not in r:而不是setdefault節省了創建大量的字典和列表對象,但是當結構很簡單時,成本並不高。

+0

感謝超級快速的答案。我的代碼出現這個錯誤:Traceback(最近一次調用最後一次):文件「」,第3行,在 KeyError:'res' – matteo

+0

這個錯誤在這段代碼中沒有發生。你實際運行了哪些代碼? –

+0

對不起我的錯;)真棒方法,謝謝! – matteo

0

對於更一般的情況下(與按鍵的任意數)

new_dict = {} 

for current_value in set(d['sp']): 
    new_dict[current_value] = {} 
    indices = [current_value == val for val in d['sp']] 

    for key, values in d.items(): 
     if key != 'sp': 
      filtered_values = [] 
      for value, index in zip(values, indices): 
       if index: 
        filtered_values.append(value) 

      new_dict[current_value][key] = filtered_values 
相關問題