2016-12-01 109 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 
相关问题