Общие элементы списков из словарей Python
Всем привет. Столкнулся с проблемой поиска оптимального решения задачи, заключающиеся в поиске совпадений в списках, состоящих из словарей. Для примера есть два списка: в первом списке два словаря, во втором один. Нужно проверить, если ли у этих списков общие словари. Операции со множествами здесь не подходят, т.к элементами являются словари. Также хочется обойтись без перебора элементов через циклы. Варианты списков: есть общие элементы, нет общих элементов, списки полностью совпадают, пустые списки. Пример исходных данных:
a = [
{
"field_id": 664395,
"field_code": "1234",
"field_type": "text",
"values": [
{
"value": "yutyuyt",
"enum_code": "WORK"
}
]
},
{
"field_id": 664393,
"field_code": "4321",
"field_type": "int",
"values": [
{
"value": "203040",
"enum_id": 1072543,
"enum_code": "WORK"
}
]
}
]
b = [
{
"field_id": 664395,
"field_code": "1234",
"field_type": "text",
"values": [
{
"value": "yutyuyt",
"enum_code": "WORK"
}
]
}
]
Ответы (2 шт):
Как вариант использовать комбинацию из Lambda и Filter функций
print(list(filter(lambda x: x in b, a)))
Результат
[{'field_id': 664395, 'field_code': '1234', 'field_type': 'text', 'values': [{'value': 'yutyuyt', 'enum_code': 'WORK'}]}]
В данном примере не выполнены условия топикстартера это к комментарию @Сергей про нехэшируемый тип
from typing import Iterable
a = [
{
"field_id": 664395,
"field_code": "1234",
"field_type": "text",
"values": [
{
"value": "yutyuyt",
"enum_code": "WORK"
}
]
},
{
"field_id": 664393,
"field_code": "4321",
"field_type": "int",
"values": [
{
"value": "203040",
"enum_id": 1072543,
"enum_code": "WORK"
}
]
}
]
b = [
{
"field_id": 664395,
"field_code": "1234",
"field_type": "text",
"values": [
{
"value": "yutyuyt",
"enum_code": "WORK"
}
]
}
]
from dataclasses import dataclass, asdict
@dataclass()
class DictItem:
field_id: int
field_code: str
field_type: str
values: list
def __hash__(self):
return hash(
(self.field_id,
self.field_code,
self.field_type,
# сюда еще можно добавить сортировку при создании кортежа
# в этом случае изначальный порядок полей будет не важен
tuple((k, v) for elem in self.values for k, v in elem.items())
)
)
aset = set(map(lambda x: DictItem(**x), a))
bset = set(map(lambda x: DictItem(**x), b))
res, *_ = aset & bset
print(asdict(res))
# {'field_id': 664395, 'field_code': '1234', 'field_type': 'text', 'values': [{'value': 'yutyuyt', 'enum_code': 'WORK'}]}