Уникальные значения словаря фильтра 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 исходного словаря.

Спасибо, парни


person matteo    schedule 01.12.2016    source источник


Ответы (2)


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 позволяет сэкономить на создании большого количества объектов словарей и списков, но когда структура проста, это не требует больших затрат.

person Dan D.    schedule 01.12.2016
comment
спасибо за супер быстрый ответ. Я получаю эту ошибку с вашим кодом: Traceback (последний последний вызов): файл ‹input›, строка 3, в ‹module› KeyError: 'res' - person matteo; 01.12.2016
comment
Эта ошибка не возникает в этом коде. Какой код вы на самом деле запускали? - person Dan D.; 01.12.2016

Для более общего случая (с произвольным количеством ключей)

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
person blue_note    schedule 01.12.2016