#python #list #dictionary
#python #Список #словарь
Вопрос:
У меня есть список задач, которые содержат task1
и task2
. Я не хочу добавлять, task3
если record_id
of 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 имеют одинаковые значения, хотя и в разном порядке, что приемлемо.
Комментарии:
1.
I don't want to append task 3 if one of the keys of task3 matches the existing tasks.
Могут ли две задачи быть помечены как идентичные, еслиrecord_id
содержат одинаковое значение? Можете ли вы уточнить?2. @arsho извините, пожалуйста, посмотрите мои правки. Только если record_id совпадает, то 2 задачи считаются идентичными.
Ответ №1:
вы должны сравнить все задачи в списке с 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 для сравнения двух списков без учета индекса элементов списка.
Ответ №2:
Если значения record_id всегда являются целыми числами, вы можете отсортировать их после преобразования в целые числа. Тогда вы сможете легко сравнивать. Если вы хотите, чтобы я уточнил, пожалуйста, дайте мне знать.
Ответ №3:
Попробуйте это :
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
список.
Ответ №4:
Одним из решений является использование класса в качестве оболочки. Этот класс может наследоваться 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
используется для отображения списка с правильным отступом.