如何使用键比较在词典列表中查找特定词典

时间:2019-03-21 06:39:28

标签: python list dictionary

我有一个包含task1task2的任务列表。如果task3的{​​{1}}与现有任务匹配,我不想附加record_id。因此,简而言之,如果列表task3中2个项目中的record_id具有相同的值,则该任务被视为相同。

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应该与task3相匹配,因为它们的task1的值相同,即使顺序不同,这是可以接受的。

4 个答案:

答案 0 :(得分:0)

如果record_id值始终是整数,则可以在转换为整数后对其进行排序。然后,您可以轻松进行比较。如果您想让我详细说明,请告诉我。

答案 1 :(得分:0)

尝试一下:

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列表中。

答案 2 :(得分:0)

一种解决方案是使用类作为包装器。该类可以继承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用于显示带有适当缩进的列表。

答案 3 :(得分:0)

您应该通过以下方式将列表中的所有任务与task3进行比较:

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比较两个列表,而不考虑列表项的索引。