Как выполнить такое разделение для dict, когда значения в dict представляют собой список?

#python #python-3.x

#python #python-3.x

Вопрос:

У меня есть dict, где ключ — строка, значение — список, содержащий некоторые числа, такие как d в коде. Я хочу вернуть список, где каждый элемент представляет собой dict, содержащий все ключи во входном dict и содержащий значение в порядке возрастания, такое как результат в коде. Предположим, мы не знаем, сколько элементов в списке (может быть не 3 или 4 в коде), но количество элементов одинаковое.

например, 1:

 d = {'1': [11, 12, 13], '2': [21, 22, 23], '3': [31, 32, 33]}
# ???
result = [{'1': 11, '2': 21, '3': 31},
          {'1': 12, '2': 22, '3': 23},
          {'1': 13, '2': 23, '3': 33}]
  

например, 2:

 d = {'1': [11, 12, 13, 14], '2': [21, 22, 23, 24], '3': [31, 32, 33, 34]}
# ???
result = [{'1': 11, '2': 21, '3': 31},
          {'1': 12, '2': 22, '3': 23},
          {'1': 13, '2': 23, '3': 33},
          {'1': 14, '2': 24, '3': 34}, ]
  

Комментарии:

1. Что вы пробовали? Гарантированно ли, что списки в исходном dict будут в порядке возрастания? (потому что вы не указали, что они есть, но оба ваших примера учитывают это предварительное условие).

2. Редактировать: что означает «увеличение», это сохранение исходного порядка в списке, а не что-то вроде численного увеличения.

Ответ №1:

zip все значения перечислены вместе, затем заархивируйте каждое полученное tuple значение с ключами, чтобы создать новые dict значения:

 result = [dict(zip(d, vs)) for vs in zip(*d.values())]
  

Попробуйте онлайн!

Это работает, потому что порядок итерации a dict согласуется с порядком итерации его значений (порядок вставки указан в версии 3.6 , но он согласован для данного запуска Python для всех версий); ключи из d в «каждом цикле» zip будут повторяться в том же порядке, в каком значения были извлечены в начале zip .

Предполагается, что под «порядком возрастания» вы подразумеваете «сохранение порядка ввода»; если это не так, было бы необходимо разумное использование sorted встроенной функции.

Комментарии:

1. Большое спасибо! Это именно то, что мне нужно!

Ответ №2:

Предполагая, что ваш список значений отсортирован, следующий код отлично работает для получения желаемого результата.

 def answer(testdict):
    result = []
    lengths = [len(v) for v in testdict.values()]
    length = lengths[0]
    for i in range(length):
        newdict = {}
        for j in testdict:
            newdict[j] = testdict[j][i]
        result.append(newdict)
    print(result)
  

Однако, если список значений не отсортирован, попробуйте сначала использовать sorted .

Комментарии:

1. Я предпочитаю использовать реализацию без цикла, но все равно большое спасибо.