Если по умолчанию стоит дорого, тест на ключ:
или если stats[field]
может быть пустым:
item = stats[field] if field in stats else very_expensive_initializer(field)
item.add(value)
Оба or
и условное выражение оцениваются лениво.
Вы все еще можете сделать это одним лайнером, но я не уверен, что вам следует. Вышеупомянутое соответствует вашему исходному коду.
Отметьте, что это не Добавить very_expensive_initializer(field)
в stats
! Вы можете сделать это тоже:
if field not in stats:
stats[field] = very_expensive_initializer(field)
или
try:
item = stats[field]
except KeyError:
item = stats[field] = very_expensive_initializer(field)
где вы выбираете первый, если field
является обычно не найден в stats
, последний, если field
только иногда не найден в stats
.
Вашего следующий вариант подкласс dict
и добавить __missing__
метод:
class subclassed_dict(dict):
def __missing__(self, key):
item = self[key] = very_expensive_initializer(key)
return item
затем использовать это в качестве stats
:
stats = subclassed_dict()
Python будет вызывать __missing__
всякий раз, когда вы пытаетесь получить доступ к ключу, который не но там.
Демонстрация:
>>> def very_expensive_initializer(field):
... print 'Doing loads of work'
... return set()
...
>>> class subclassed_dict(dict):
... def __missing__(self, key):
... item = self[key] = very_expensive_initializer(key)
... return item
...
>>> stats = subclassed_dict()
>>> stats['foo'].add(2)
Doing loads of work
>>> stats['foo'].add(3)
>>> stats['foo'].add(4)
>>> stats['bar']
Doing loads of work
set([])
>>> stats['bar']
set([])
не должны 'статистике = DICT()' 'быть статистика = dict' –
@KDawG Нет, это не должно быть –
@DavidHeffernan, но не вызывает ли объект 'TypeError: 'dict' не вызываемый' –