Пример - искусственный, но у меня были подобные проблемы много раз.
db_file_names = ['f1', 'f2'] # list of database files
def make_report(filename):
# read the database and prepare some report object
return report_object
Теперь я хочу создать словарь: db_version -> number_of_tables. Объект отчета содержит всю необходимую информацию.
Словарь может выглядеть так:
d = {
make_report(filename).db_version: make_report(filename).num_tables
for filename in db_file_names
}
Этот подход иногда работает, но очень неэффективен: отчет готовится дважды для каждой базы данных.
Чтобы избежать этой неэффективности, я обычно использую один из следующих подходов:
Использовать временное хранилище:
reports = [make_report(filename) for filename in db_file_names]
d = {r.db_version: r.num_tables for r in reports}
Или используйте какой-нибудь адаптер-генератор:
def gen_data():
for filename in db_file_names:
report = make_report(filename)
yield report.db_version, report.num_tables
d = {dat[0]: dat[1] for dat in gen_data()}
Но обычно только после того, как я напишу какое-то неправильное понимание, продумал и осознал, что в этом случае чистое и простое понимание невозможно.
Вопрос в том, есть ли лучший способ создать требуемый словарь в таких ситуациях?
Со вчерашнего дня (когда я решил опубликовать этот вопрос) я изобрел еще один подход, который мне нравится больше, чем все остальные:
d = {
report.db_version: report.num_tables
for filename in db_file_names
for report in [make_report(filename), ]
}
но даже этот выглядит не очень хорошо.