Общий принцип такой: надо постоянно отсекать понемногу от общей массы и потом работать с тем, что осталось.
Общий принцип такой: надо
итеративным образом отсекать
понемногу от общей массы, оставляя
максимум от всего остального, и потом работать с тем, что осталось, повторяя всю эту процедуру снова для оставшейся общей массы. Это процесс декомпозиции.
Это как есть торт: надо отрезать по кусочку, съедать кусочек, потом снова отрезать кусочек и съедать кусочек, и так далее, так ты съешь весь торт; если же ты его будешь сразу заталкивать весь в рот и пытаться проглатывать его весь, то можно и вовсе подавиться этим всем и задохнуться в итоге.
>>> d1 = {
... 'ab': [
... {'a': 'Ivan', 'b': 10},
... {'a': 'Ivan', 'b': 20},
... {'a': 'Egor', 'b': 15},
... {'a': 'Egor', 'b': 5},
... {'a': 'Petya', 'b': 7},
... {'a': 'Petya', 'b': 17},
... {'a': 'Vasya', 'b': 8},
... {'a': 'Vasya', 'b': 12}
... ]
... }
>>>
>>> d2 = {
... 'cde': [
... {'c': 'Ivan', 'd': 5, 'e': 15},
... {'c': 'Petya', 'd': 15, 'e': 18},
... {'c': 'Vasya', 'd': 10, 'e': 18},
... {'c': 'Egor', 'd': 1, 'e': 10}
... ]
... }
>>>
>>> lst1 = d1['ab']
>>> lst2 = d2['cde']
>>>
>>> tmp = []
>>> for i in lst2:
... t = [d for d in lst1
... if d['a'] == i['c']
... and i['d'] < d['b'] < i['e']]
... tmp.append(t)
...
>>> out = []
>>> for i in tmp:
... for d in i:
... out.append((d['a'], d['b']))
...
>>> out
[('Ivan', 10), ('Petya', 17), ('Vasya', 12), ('Egor', 5)]
>>>
Тут сначала структура словаря отделена от списков, с которыми надо работать. Чтобы с этими списками работать, структура общего словаря не нужна, поэтому отрезаем её и выкидываем. Дальше работаем только со списками словарей.
Затем нам надо выбрать нужные словари из списков, не делая ничего с ними, поэтому сами списки, которые нам не нужны со всеми ненужными словарями в них, мы отрезаем и выкидываем.
И потом, получив нужные словари, мы уже работаем только с ними и начинаем их выводить как-то или выбирать что-то из них.
С каждым шагом остаётся все меньше данных и они становятся всё точнее и определённее.