Два подхода к инициализации и обновлению сложного словаря: попробуйте/исключение или .get(x)Python

Программы на Python
Ответить
Anonymous
 Два подхода к инициализации и обновлению сложного словаря: попробуйте/исключение или .get(x)

Сообщение Anonymous »

В ходе проверки кода обсуждались два следующих подхода к инициализации сложного словаря. Обсуждались вопросы производительности, что легко читать, а что нет, какой подход наименее подвержен ошибкам при сопровождении кода и так далее. Конечно, дискуссия разделилась на два лагеря, поэтому я поставил вопрос здесь, чтобы получить отзывы от других программистов, которые, надеюсь, смогут помочь другим, создающим сложные словари.
Метод add_data вызывается в цикл, добавляя в словарь все больше и больше данных.
Подход 1:

Код: Выделить всё

def add_data(data, station, departure_date, departure_time, train_id, train_type, category, crewmember, meals):
station_id = station['id']
station_descr = station['descr']
try:
data[departure_date]
except KeyError:
data[departure_date] = {}
try:
data[departure_date][station_id]
except KeyError:
data[departure_date][station_id] = {
'descr': station_descr,
'trains': {}
}
try:
data[departure_date][station_id]['trains'][departure_time]
except KeyError:
data[departure_date][station_id]['trains'][departure_time] = {}
try:
data[departure_date][station_id]['trains'][departure_time][train_id]
except KeyError:
data[departure_date][station_id]['trains'][departure_time][train_id] = {
'train_type': train_type
}
try:
data[departure_date][station_id]['trains'][departure_time][train_id][category]
except KeyError:
role_dict = {
'snack_meals': 0,
'cold_meals': 0,
'hot_meals': 0,
'crew': []
}
data[departure_date][station_id]['trains'][departure_time][train_id][category] = copy.deepcopy(role_dict)

meal_match = re.match(r"snack_meals: (\d+), cold_meals: (\d+), hot_meals: (\d+)", meals)
data[departure_date][station_id]['trains'][departure_time][train_id][category]['snack_meals'] += int(meal_match[1])
data[departure_date][station_id]['trains'][departure_time][train_id][category]['cold_meals'] += int(meal_match[2])
data[departure_date][station_id]['trains'][departure_time][train_id][category]['hot_meals'] += int(meal_match[3])

data[departure_date][station_id]['trains'][departure_time][train_id][category]['crew'].append({
'alias': crewmember.getAlias(),
'name': crewmember.getGivenNames(),
'surname': crewmember.getSurname()
})
Подход 2:

Код: Выделить всё

def add_data(data, station, departure_date, departure_time, train_id, train_type, category, crewmember, meals):
station_id = station['id']
station_descr = station['descr']
if not data.get(departure_date):
data[departure_date] = {}
if not data[departure_date].get(station_id):
data[departure_date][station_id] = {
'descr': station_descr,
'trains': {}
}
if not data[departure_date][station_id]['trains'].get(departure_time):
data[departure_date][station_id]['trains'][departure_time] = {}
if not data[departure_date][station_id]['trains'][departure_time].get(train_id):
data[departure_date][station_id]['trains'][departure_time][train_id] = {
'train_type': train_type
}
if not data[departure_date][station_id]['trains'][departure_time][train_id].get(category):
role_dict = {
'snack_meals': 0,
'cold_meals': 0,
'hot_meals': 0,
'crew': []
}
data[departure_date][station_id]['trains'][departure_time][train_id][category] = copy.deepcopy(role_dict)

data[departure_date][station_id]['trains'][departure_time][train_id][category]['snack_meals'] += int(meal_match[1])
data[departure_date][station_id]['trains'][departure_time][train_id][category]['cold_meals'] += int(meal_match[2])
data[departure_date][station_id]['trains'][departure_time][train_id][category]['hot_meals'] += int(meal_match[3])
data[departure_date][station_id]['trains'][departure_time][train_id][category]['crew'].append({
'alias': crewmember.getAlias(),
'name': crewmember.getGivenNames(),
'surname': crewmember.getSurname()
})
Исключения считаются более тяжелыми по сравнению с операторами if, но тест производительности показал, что подход 1, решение try/Exception, был на 1/3 быстрее, чем подход 2. >
Итак, мой вопрос: почему в данном конкретном случае вы предпочитаете один подход другому?
Я знаю, что это может быть субъективный вопрос, но, пожалуйста, постарайтесь взглянуть на это объективно.

Подробнее здесь: https://stackoverflow.com/questions/793 ... ept-or-get
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»