Во-первых, вы должны использовать функции, чтобы избежать избыточности:
def before_after(hello, result):
"""result = '_0_result' (before) or '_1_result' (after)"""
portfolios = {k:v for k,v in hello.items() if '.some_list' in k}
hello_deltas = {k:v for k,v in hello.items() if '/delta[' or '/fast_spot[' or '/composite_delta_fx[' in k}
hello_before_after = {k:v for k,v in hello_deltas.items() if result in k}
some_list_before_after = {}
for some_list in portfolios.values():
for some in some_list:
a = [i for i in hello_before_after.keys() if str(some) in i]
if len(a) != 0:
some_list_before_after[some] = a
return some_list_before_after
Затем, прежде чем погрузиться в понимание списка, посмотрите на код: вы создаете промежуточный словарь, но вы можете использовать генератор:
portfolios_lists = (v for k,v in hello.items() if '.some_list' in k)
for some_list in portfolios_lists:
for some in some_list:
...
Или, лучше:
portfolios_somes = (s for k,v in hello.items() for s in v if '.some_list' in k)
for some in portfolios_somes:
...
Вы используете только ключи от hello_deltas
:
hello_deltas_before_after = [k for k in hello.keys() if result in k and ('/delta[' or '/fast_spot[' or '/composite_delta_fx[' in k)]
Примечание: с функцией вы можете подумать, что вы будете проверять, если'/delta[' or '/fast_spot[' or '/composite_delta_fx[' in k
дважды: один для before
и один для after
.На самом деле это не так: сначала вы проверяете, стоит ли result in k
(то есть '_0_result' in k
или '_0_result' in k
) и , а затем сделать дорогостоящий тест.
Код теперь выглядит следующим образом:
def before_after(hello, result):
portfolios_somes = (s for k,v in hello.items() for s in v if '.some_list' in k)
hello_deltas_before_after = [k for k in hello.keys() if result in k and ('/delta[' or '/fast_spot[' or '/composite_delta_fx[' in k)]
some_list_before_after = {}
for some in portfolios_somes:
a = [i for i in hello_deltas_before_after if str(some) in i]
if len(a) != 0:
some_list_before_after[some] = a
return some_list_before_after
Теперь, определение слова:
some_list_before_after = {
some: a
for some in portfolios_somes
for a in ([i for i in hello_deltas_before_after if str(some) in i], )
if a}
Кортеж из одного элемента - это трюк для вычисления a
только один раз.Полный код (не проверено):
def before_after(hello, result):
portfolios_somes = (s for k, v in hello.items() for s in v if '.some_list' in k)
hello_deltas_before_after = [k for k in hello.keys() if result in k and ('/delta[' or '/fast_spot[' or '/composite_delta_fx[' in k)]
return {
some: a
for some in portfolios_somes
for a in ([i for i in hello_deltas_before_after if str(some) in i], )
if a}
Это должно быть быстрее, чем оригинальная версия, но проблема имеет (очень приблизительно) O (n ^ 2) временную сложность, и вы не получите результат турачерез секунду.Попробуйте это на подмножестве исходных данных (например, hello_short = dict(itertools.islice(hello.items(), 1000))
).