Как вставить данные в массив словарей в порядке, не пропуская данные через регулярное выражение - PullRequest
0 голосов
/ 26 марта 2020

Это мой код:

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

Код:


test_list = {'module_serial-1': 'PSUXA12345680', 'module_name-1': 'CH1.FM5', 'module_name-2': 'CH1.FM6', 'module_serial-2': 'PSUXA12345681'}

def parse_subdevice_modules(row):
  modules = []
  module = {}

  for k, v in row.items():
    if v:
        if re.match("module_name", k):
            module['name'] = v
        if re.match("module_serial", k):
            module['serial'] = v
            modules.append(module)
            module = {}

  return modules

print(parse_subdevice_modules(test_list))

Ожидаемый вывод: [{'name': 'CH1.FM5', serial ':' PSUXA12345680 '}, {' name ':' CH1.FM6 ',' serial ':' PSUXA12345681 '}] Фактический вывод: ['serial': 'PSUXA12345680'}, {'name': 'CH1.FM6', 'serial': 'PSUXA12345681'}]

Запустите его здесь: https://repl.it/repls/WetSteelblueRange

Обратите внимание, что порядок данных test_list не может быть изменен, так как он поступает через внешний API, поэтому я использовал regex. Любые идеи будут оценены.

Ответы [ 3 ]

1 голос
/ 26 марта 2020

Ваш код основан на неверном предположении, что ключи заказаны и что серийный номер всегда будет следовать за именем. Правильное решение здесь - использовать dict (на самом деле collections.defaultdict, чтобы упростить задачу) для сбора и перегруппировки интересующих вас значений на основе номера модуля (последний ключ -N в ключе). Обратите внимание, что здесь вам не нужно регулярное выражение - строка Python уже обеспечивает необходимые операции для этой задачи:

from collections import defaultdict

def parse_subdevice_modules(row):
    modules = defaultdict(dict)

    for k, v in row.items():
        # first get rid of what we're not interested in
        if not v:
            continue
        if not k.startswith("module_"):
            continue

        # retrieve the key number (last char) with 
        # negative string indexing: 
        key_num = k[-1]

        # retrieve the useful part of the key ("name" or "serial")
        # by splitting the string:
        key_name = k.split("_")[1].split("-")[0]

        # and now we just have to store this in our defaultdict
        modules[key_num][key_name] = v

    # and return only the values.
    # NB: in py2.x you don't need the call to `list`, 
    # you can just return `modules.values()` directly

    modules = list(modules.values())
    return modules



test_list = {
    'profile': '', 'chassis_name': '123', 'supplier_order_num': '',
    'device_type': 'mass_storage', 'device_subtype': 'flashblade',
    'module_serial-1': 'PSUXA12345680', 'module_name-1': 'CH1.FM5',
    'module_name-2': 'CH1.FM6', 'rack_total_pos': '',
    'asset_tag': '002000027493', 'module_serial-2': 'PSUXA12345681',
    'purchase_order': '0004530869', 'build': 'Test_Build_for_SNOW',
    'po_line_num': '00190', 'mac_address': '', 'position': '7',
    'model': 'FB-528TB-10X52.8TB', 'manufacturer': 'PureStorage',
    'rack': 'Test_Rack_2', 'serial': 'PMPAM1842147D', 'name': 'FB02'
}

print(parse_subdevice_modules(test_list))
1 голос
/ 26 марта 2020

Вы также можете сделать что-то подобное.


test_list = {'module_serial-1': 'PSUXA12345680', 'module_name-1': 'CH1.FM5', 'module_name-2': 'CH1.FM6',
             'module_serial-2': 'PSUXA12345681'}


def parse_subdevice_modules(row):
    modules_list = []

    for key, value in row.items():
        if not value or key.startswith('module_name'):
            continue

        if key.startswith('module_serial'):
            module_name_key = f'module_name-{key.split("-")[-1]}'
            modules_list.append({'serial': value, 'name': row[module_name_key]})

    return modules_list


print(parse_subdevice_modules(test_list))

Вывод:

[{'serial': 'PSUXA12345680', 'name': 'CH1.FM5'}, {'serial': 'PSUXA12345681', 'name': 'CH1.FM6'}]
0 голосов
/ 26 марта 2020

Вам нужно проверить, содержит ли module 2 элемента и добавить его в модули:

test_list = {'module_serial-1': 'PSUXA12345680', 'module_name-1': 'CH1.FM5', 'module_name-2': 'CH1.FM6', 'module_serial-2': 'PSUXA12345681'}

def parse_subdevice_modules(row):
    modules = []
    module = {}

    for k, v in row.items():
        if v:
            if k.startswith('module_name'):
                module['name'] = v
            elif k.startswith("module_serial"):
                module['serial'] = v

            if len(module) == 2:
                modules.append(module)
                module = {}
    return modules

print(parse_subdevice_modules(test_list))

Возвращает:

[{'serial': 'PSUXA12345680'}, {'name': 'CH1.FM5'}, {'name': 'CH1.FM6'}, {'serial': 'PSUXA12345681'}]
...