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

У меня есть список задач, которые содержат task1 и task2.Я не хочу добавлять task3, если record_id из task3 соответствует существующим задачам.Короче говоря, если record_id из 2 элементов в списке tasks имеют одинаковые значения, задача считается одинаковой.

task1 = {
        'record_id': '1,2,3',
        'location': 'l1',
        'instruction_parameters': {
            'NAME': 'project_name1'
        },
        'marked_points': 'marked_points1',
        'marked_polygons': 'marked_polygons1',
    }
task2 = {
        'record_id': '8,7,3',
        'location': 'l2',
        'instruction_parameters': {
            'NAME': 'project_name2'
        },
        'marked_points': 'marked_points2',
        'marked_polygons': 'marked_polygons2',
    }

tasks = [task1, task2]

task3 = {
        'record_id': '3,1,2',
        'location': '',
        'instruction_parameters': {
            'NAME': 'project_name3'
        },
        'marked_points': 'marked_points3',
        'marked_polygons': 'marked_polygons3',
    }

task3_record_ids = task3['record_id'].split(',')

Я попробовал следующий подход, но первый дал мне ошибку StopIteration ивторой ничего не вернул.

previous_dup_task_dict = next(item for item in tasks if set(item['record_id'].split(',')) == set(task3_record_ids))

Второй подход:

previous_dup_task_dict = filter(lambda task: set(task['record_id'].split(',')) == set(record_ids), tasks)

Обратите внимание, что порядок record_id s не имеет значения, поэтому в этом случае task3 должен соответствовать task1 как их record_id s имеют одинаковые значения, хотя и в другом порядке, что приемлемо.

Ответы [ 4 ]

0 голосов
/ 21 марта 2019

Вы должны сравнить все задачи в списке с задачей 3 следующим образом:

task1 = {
    'record_id': '1,2,3',
    'location': 'l1',
    'instruction_parameters': {
        'NAME': 'project_name1'
    },
    'marked_points': 'marked_points1',
    'marked_polygons': 'marked_polygons1',
}
task2 = {
    'record_id': '8,7,3',
    'location': 'l2',
    'instruction_parameters': {
        'NAME': 'project_name2'
    },
    'marked_points': 'marked_points2',
    'marked_polygons': 'marked_polygons2',
}

tasks = [task1, task2]

task3 = {
    'record_id': '3,1,2',
    'location': '',
    'instruction_parameters': {
        'NAME': 'project_name3'
    },
    'marked_points': 'marked_points3',
    'marked_polygons': 'marked_polygons3',
}

match = False
for task in tasks: 
    if set(task3["record_id"].split(",")) == set(task["record_id"].split(",")): #set for ignoring order of list items
        match = True

if not match:
    tasks.append(task3)

print(tasks)

Вы должны использовать set для сравнения двух списков без учета индекса элементов списка.

0 голосов
/ 21 марта 2019

Попробуйте это:

task1 = ...
task2 = ...
task3 = ...
tasks = [task1, task2]
match_found = False
for task in tasks:
    if sorted(task1['record_id'].split(',')) == sorted(task3['record_id'].split(',')):
        match_found = True
    else: 
        continue

if match_found == False:
    tasks.append(task3)

Сначала назначьте переменную для проверки, присутствует ли какой-либо элемент с таким же ключом record_id в списке tasks. Теперь переберите список tasks и разделите каждый элемент record_id на ,, отсортируйте их и сравните с списком tasks3. Если они совпадают, присвойте эту переменную True. Теперь, если переменная True, добавьте task3 в список tasks.

0 голосов
/ 21 марта 2019

Одним из решений является использование класса в качестве оболочки. Этот класс может наследовать list.

import json


task1 = {
        'record_id': '1,2,3',
        'location': 'l1',
        'instruction_parameters': {
            'NAME': 'project_name1'
        },
        'marked_points': 'marked_points1',
        'marked_polygons': 'marked_polygons1',
}

task2 = {
    'record_id': '8,7,3',
    'location': 'l2',
    'instruction_parameters': {
        'NAME': 'project_name2'
    },
    'marked_points': 'marked_points2',
    'marked_polygons': 'marked_polygons2',
}

task3 = {
    'record_id': '3,1,2',
    'location': '',
    'instruction_parameters': {
        'NAME': 'project_name3'
    },
    'marked_points': 'marked_points3',
    'marked_polygons': 'marked_polygons3',
}


class Tasks(list):
    def get_identifier(self, s):
        s = s.replace(" ","")
        return sorted(list(map(int, s.split(","))))

    def compare_tasks(self, first_task, second_task):
        if self.get_identifier(first_task['record_id']) == self.get_identifier(second_task['record_id']):
            return True
        return False

    def append(self, new_task):
        task_exist = False
        for task in self:
            if self.compare_tasks(task, new_task):
                task_exist = True
                #raise ValueError('Task already in list: {}'.format(new_task))
        if task_exist == False:
            super().append(new_task)

tasks = Tasks()
tasks.append(task1)
tasks.append(task2)
tasks.append(task3)
print(json.dumps(tasks, indent = 4))

Выход:

[
    {
        "location": "l1",
        "marked_points": "marked_points1",
        "instruction_parameters": {
            "NAME": "project_name1"
        },
        "record_id": "1,2,3",
        "marked_polygons": "marked_polygons1"
    },
    {
        "location": "l2",
        "marked_points": "marked_points2",
        "instruction_parameters": {
            "NAME": "project_name2"
        },
        "record_id": "8,7,3",
        "marked_polygons": "marked_polygons2"
    }
]

Вы можете поднять ValueError для добавления дублирующейся задачи в tasks.

Чтобы поднять ValueError, раскомментируйте следующий комментарий:

#raise ValueError('Task already in list: {}'.format(new_task))

Разъяснения:

  • Tasks наследует list.
  • Каждое задание имеет уникальный идентификатор: отсортированный список клавиш record_id.
  • Две задачи идентичны, если имеют одинаковый уникальный идентификатор.
  • json.dumps используется для отображения списка с правильным отступом.
0 голосов
/ 21 марта 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...