Вы могли пройти object_pairs_hook
к json.loads
, которые будут собирать значения с одинаковыми ключами к спискам:
from collections import defaultdict
import json
s = '{"author": "SampleMan", "author":"NonSampleMan", "author":"BoringMan", "foo":"bar", "bar": [1]}'
def hook(pairs):
d = defaultdict(list)
for k, v in pairs:
d[k].append(v)
return {k: v if len(v) > 1 else v[0] for k, v in d.items()}
print(json.loads(s, object_pairs_hook=hook))
Выход:
{'bar': [1], 'author': ['SampleMan', 'NonSampleMan', 'BoringMan'], 'foo': 'bar'}
В выше крючке получает list
из (key, value)
кортежей, которые он хранит в defaultdict
где значения - это списки. После того, как он будет повторен по кортежам, он будет генерировать результат dict
, где value is list, если было несколько элементов с заданным ключом.
Python документация следующее описание крюка:
object_pairs_hook является дополнительной функцией, которая будет вызвана в результате какого-либо объекта буквального декодированного с упорядоченным списком пар. Возвращаемое значение object_pairs_hook будет использоваться вместо dict. Эта функция может использоваться для реализации пользовательских декодеров, которые полагаются на порядок декодирования пар ключей и значений (например, collection.OrderedDict() будет помнить порядок вставки). Если object_hook также определен, объект_pairs_hook имеет приоритет.