Как объединить элементы на основе одного и того же ключа/значения в списке Python

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

Вход

[{
    "category": "Nace2008",
    "code": "01110",
    "NL": "Teelt van granen (m.u.v. rijst), peulgewassen en oliehoudende zaden"
},
{
    "category": "Nace2008",
    "code": "01110",
    "FR": "Culture de c\u00e9r\u00e9ales (\u00e0 l'exception du riz), de l\u00e9gumineuses et de graines ol\u00e9agineuses"
},
{
    "category": "Nace2008",
    "code": "01120",
    "FR": "Culture du riz"
},
{
    "category": "Nace2008",
    "code": "01120",
    "NL": "Teelt van rijst"
}]

Ожидаемый результат

[{
    "category": "Nace2008",
    "code": "01110",
    "NL": "Teelt van granen (m.u.v. rijst), peulgewassen en oliehoudende zaden",
    "FR": "Culture de c\u00e9r\u00e9ales (\u00e0 l'exception du riz), de l\u00e9gumineuses et de graines ol\u00e9agineuses"
},
{
    "category": "Nace2008",
    "code": "01120",
    "NL": "Teelt van rijst",
    "FR": "Culture du riz"
}]

Перебор списка и повторный цикл для проверки той же категории и кода приведет к дублированию данных.

что должно произойти, если ключи Другие совпадут или не совпадут?

juanpa.arrivillaga 09.04.2022 12:01

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

Thore 09.04.2022 12:04

ты хотел сказать "code": "01110"?? Поскольку ваш вывод подразумевает, что вы хотите сопоставить "code":"0111" с "code":"01110"

juanpa.arrivillaga 09.04.2022 12:04

Проверка здесь должна быть, если другие объекты в списке имеют одинаковое значение для ключей category и code

Thore 09.04.2022 12:08

Мой плохой, я сделал опечатку. Исправил в вопросе

Thore 09.04.2022 12:09

Я бы использовал словарь, в котором значения для ключей являются ключом в словаре… например: {“Nace2008_01110”: {object}}, тогда вы можете найти его с помощью вызова .get, а затем добавить новый языковой ключ и значение для каждого последующего совпадения. Вы можете написать это как функцию, чтобы вы могли передавать ключи, которые хотите проверить на уникальность…

Jarvis 09.04.2022 12:09

Кажется, ответ ниже показывает код, аналогичный моему предложению выше, но с использованием кортежа для ключа, что лучше! Великие умы думают одинаково!

Jarvis 09.04.2022 12:15
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
0
7
30
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, вам просто нужна стандартная идиома группировки словарей на основе описанного вами ключа:

>>> data = [{
...     "category": "Nace2008",
...     "code": "01110",
...     "NL": "Teelt van granen (m.u.v. rijst), peulgewassen en oliehoudende zaden"
... },
... {
...     "category": "Nace2008",
...     "code": "01110",
...     "FR": "Culture de c\u00e9r\u00e9ales (\u00e0 l'exception du riz), de l\u00e9gumineuses et de graines ol\u00e9agineuses"
... },
... {
...     "category": "Nace2008",
...     "code": "01120",
...     "FR": "Culture du riz"
... },
... {
...     "category": "Nace2008",
...     "code": "01120",
...     "NL": "Teelt van rijst"
... }]

Итак, создайте пустой словарь, сгруппируйте по ключу:

>>> result = {}
>>> for d in data:
...     key = d['category'], d['code']
...     result.setdefault(key, {}).update(d)
...

Обратите внимание, .update просто наивно объединяет все, что есть. Если у вас будут дубликаты ключей в последующих записях, то будет использоваться последний. Если они все уникальны, это не должно быть проблемой. И результаты:

>>> from pprint import pprint
>>> pprint(result)
{('Nace2008', '01110'): {'FR': "Culture de céréales (à l'exception du riz), de "
                               'légumineuses et de graines oléagineuses',
                         'NL': 'Teelt van granen (m.u.v. rijst), peulgewassen '
                               'en oliehoudende zaden',
                         'category': 'Nace2008',
                         'code': '01110'},
 ('Nace2008', '01120'): {'FR': 'Culture du riz',
                         'NL': 'Teelt van rijst',
                         'category': 'Nace2008',
                         'code': '01120'}}

Затем вы можете извлечь значения этого словаря, если хотите:

>>> pprint(list(result.values()))
[{'FR': "Culture de céréales (à l'exception du riz), de légumineuses et de "
        'graines oléagineuses',
  'NL': 'Teelt van granen (m.u.v. rijst), peulgewassen en oliehoudende zaden',
  'category': 'Nace2008',
  'code': '01110'},
 {'FR': 'Culture du riz',
  'NL': 'Teelt van rijst',
  'category': 'Nace2008',
  'code': '01120'}]

Обратите внимание, что групповую идиому можно немного подчистить, используя defaultdict (некоторых людей .setdefault сбивает с толку):

from collections import defaultdict
result = defaultdict(dict)
for d in data:
    key = d['category'], d['code']
    result[key].update(d)

Оба такие же, как:

result = {}
for d in data:
    key = d['category'], d['code']
    if key not in result:
        result[key] = {}
    result[key].update(d)

Если у объекта должен быть другой ключ address (полностью случайный), и я хочу сохранить их обоих, объединив две строки или два объекта (если адрес является объектом с street, number и т. д.). Должен ли я изменить функцию обновления на пользовательскую функцию слияния, чтобы справиться с этим?

Thore 09.04.2022 12:27

@Thore да, вы захотите написать собственную функцию обновления для обработки вещей.

juanpa.arrivillaga 09.04.2022 12:28

Другие вопросы по теме