Словарь: добавление к значению списка, когда ключ является кортежем - PullRequest
0 голосов
/ 02 февраля 2020

Я пытаюсь добавить значения в список, где ключ является кортежем. Но я продолжаю получать keyError, потому что словарь в python не может получить доступ к кортежу в качестве ключа.

Примечание: что я пытаюсь сделать:

  1. У меня есть json файл. Я пытаюсь сгруппировать по n пунктов, которые будут моим ключом для словаря. Затем я верну соответствующий список словаря для ключа кортежа.
  2. Я пытаюсь сделать это в функции.

Найдите мой пример кода ниже:

def group_by_field(data, fields):
    if len(fields) > 1:
        groups = {fields: []}
        for parameter in data:
            for k, v in groups.items():
                for i in fields:
                    if i in k:
                        groups[parameter[k]].append(parameter)
        return groups

Ниже приведен пример, где я пытаюсь реализовать функцию:

group_by_field(scripts, ('bnf_name', 'bnf_code'))

, где scripts - это json файл

Вот что такое json объект, scripts, выглядит так:

[{'bnf_code': '0101010G0AAABAB',
  'items': 2,
  'practice': 'N81013',
  'bnf_name': 'Co-Magaldrox_Susp 195mg/220mg/5ml S/F',
  'nic': 5.98,
  'act_cost': 5.56,
  'quantity': 1000},
 {'bnf_code': '0101021B0AAAHAH',
  'items': 1,
  'practice': 'N81013',
  'bnf_name': 'Alginate_Raft-Forming Oral Susp S/F',
  'nic': 1.95,
  'act_cost': 1.82,
  'quantity': 500}]

Вот как должен выглядеть пример вывода:

{('Co-Magaldrox_Susp 195mg/220mg/5ml S/F', '0101010G0AAABAB'): [{'bnf_code': '0101010G0AAABAB',
      'items': 2,
      'practice': 'N81013',
      'bnf_name': 'Co-Magaldrox_Susp 195mg/220mg/5ml S/F',
      'nic': 5.98,
      'act_cost': 5.56,
      'quantity': 1000}],
 ('Alginate_Raft-Forming Oral Susp S/F', '0101021B0AAAHAH'): [{'bnf_code': '0101021B0AAAHAH',
      'items': 1,
      'practice': 'N81013',
      'bnf_name': 'Alginate_Raft-Forming Oral Susp S/F',
      'nic': 1.95,
      'act_cost': 1.82,
      'quantity': 500}]

Ответы [ 2 ]

0 голосов
/ 03 февраля 2020

У вас есть много проблем:

  • , когда вы пытаетесь добавить что-то к groups[parameter[k]], k имеет значение ('bnf_name', 'bnf_code') и явно не содержит scripts.
  • , даже если вы решите предыдущую проблему, parameter[k] не будет существовать в groups
  • , вы изменяете словарь groups во время итерации, что запрещено.

И вопрос: что вернет, если len(fields) <= 1? None? пустой дикт? Я предлагаю вам вернуть пустой текст или выдать ошибку.

Попробуйте:

def group_by_field(data, fields):
    if len(fields) <= 1:
        return {}

    groups = {}
    for parameter in data:
        key = tuple(parameter[k] for k in fields)
        groups.setdefault(key, []).append(parameter)

    return groups

Создайте ключ из поля ('bnf_name', 'bnf_code'): ('Co-Magaldrox_Susp 195mg/220mg/5ml S/F', '0101010G0AAABAB'), ... используя tuple (который можно стирать). А затем добавьте текущий dict в список groups[key]. Если этот список еще не существует, он создается setdefault.

0 голосов
/ 03 февраля 2020

Ошибка в том, что вы пытаетесь использовать keu ('bnf_name', 'bnf_code') для доступа к данным в объекте, подобном следующему, и этот ключ кортежа не существует.

{'bnf_code': '0101010G0AAABAB', 'items': 2, 'practice': 'N81013', 'bnf_name': 'Co-Magaldrox_Susp 195mg/220mg/5ml S/F', 'nic': 5.98, 'act_cost': 5.56, 'quantity': 1000}

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

def build_with_keys(values, fields):
    if len(fields) > 1:
        result = {}
        for value in values:
            key = tuple(value[k] for k in fields)
            result[key] = value
        return result
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...