как мне объединить два списка [dict] и правильно упорядочить по его идентификатору?

#python #json

#python #json

Вопрос:

Я пытаюсь объединить два list[dict] в следующий формат и упорядочить как техники, так и субтехнику, но я не уверен, как правильно объединить их, не затрагивая другие техники

 techniques = [{
   "technique_id":"T1548",
   "technique":"demo",
   "url":"url",
   "tactic":[
      "demo",
      "demo"
   ]
}]


subtechniques = [{
   "technique_id":"T1548.002",
   "technique":"demo",
   "url":"url"
}]


def merge_techniques(techniques, subtechniques):
    change_list = []
    for x in techniques:
        for y in subtechniques:
            if x['technique_id'] == y['technique_id'].split('.')[0]:
                print(x)
                print(y)
    return change_list


merge_techniques(techniques, subtechniques)
 

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

 {
   "technique_id":"T1548",
   "technique":"dmep",
   "url":"https://xxxxxxxxxxxx",
   "tactic":[
      "xxxxxxxxxxxx",
      "xxxxxxxxxxxx"
   ],
   "subtechnique": [
       {
        "technique_id":"T1548.002",
        "technique":"demo",
        "url":"url"
       }
    ]
}
 

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

1. ваш желаемый результат, похоже, содержит довольно много ошибок или, по крайней мере, несоответствий с вводом.

2. Я обновляю dict для лучшего понимания @PaulH

3. откуда dmep берется? в основе это кажется вопросом с простым ответом, если бы вы могли представить четкое требование к выводу. то, что у вас есть, совсем не понятно. удалите 90% того, что у вас есть, и просто оставьте его в виде 2 списков с минимальными dicts в них. что вы хотите получить в качестве вывода? тот факт, что ваши dicts в настоящее время сложны, ничего не добавляет к вашему вопросу, это только сбивает нас с толку и заставляет вас работать сверхурочно, чтобы исправить несоответствия в ваших образцах.

4. @JLPeyret dmep — это просто образец данных. так что не беспокойтесь о данных. Мне просто нужно следовать формату вывода через поиск, если у родителя есть дочерние подтексты

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

Ответ №1:

Если вы не хотите создавать новый объект, вы можете отказаться от операций копирования.

 import copy

def merge_techniques(techniques, subtechniques):
    result = []
    # create technique_id dictionary
    techniques_dict = dict()
    for tech in techniques:
        # create new object
        tech_copy = copy.copy(tech)
        
        techniques_dict[tech['technique_id']] = tech_copy
        result.append(tech_copy)
    
    # visit all sub techniques
    for subtech in subtechniques:
        tech_id = subtech['technique_id'].split('.')[0]
        
        # search by tech_id 
        if tech_id not in techniques_dict:
            # if not found
            print('Tech %s is not found'%(tech_id))
            continue
        
        # get tech by tech_id
        tech = techniques_dict[tech_id]
        
        # create subtechnique array if not existed
        if 'subtechnique' not in tech:
            tech['subtechnique'] = []
            
        # copy subtech object
        tech['subtechnique'].append(copy.copy(subtech))
    
    return result