Важно знать методы get
и setdefault
, они должны быть в наборе инструментов любого программиста Python.
Еще один важный способ сделать это - использовать collections.defaultdict
, потому что тогда вы можете определитьВаше «значение по умолчанию» в одном месте без необходимости разбрасывать его по всему коду, где бы ни использовался словарь, т.е. не повторять себя.Затем, если вы измените значение по умолчанию, вам не нужно искать код, находя все эти get и setdefaults.Например,
>>> import collections
>>> myDict = collections.defaultdict
>>> myDict = collections.defaultdict(lambda : 1024)
>>> myDict[0] += 1
>>> print myDict[0], myDict[100]
1025 1024
Поскольку вы можете установить вызов функции, вы можете делать все что угодно для значения по умолчанию.Как насчет присвоения случайного значения от 1 до 10 для каждого нового ключа?
>>> import collections
>>> import random
>>> myDict = collections.defaultdict(lambda : random.randint(1,10))
>>> print myDict[0], myDict[100]
1 5
>>> print myDict[0], myDict[100], myDict[2]
1 5 6
Хорошо, этот пример немного надуманный, но я уверен, что вы можете придумать лучшее применение.Скажем, у вас есть дорогой класс для создания - экземпляр создается только в том случае, если ключ на самом деле отсутствует, в отличие от вызовов get
и setdefault
, например,
>>> class ExpensiveClass(object):
>>> numObjects = 0
>>> def __init__(self):
>>> ExpensiveClass.numObjects += 1
>>>
>>> print ExpensiveClass.numObjects
0
>>> x = {}
>>> x[0] = ExpensiveClass()
>>> print ExpensiveClass.numObjects
1
>>> print x.get(0, ExpensiveClass())
<__main__.ExpensiveClass object at 0x025665B0>
>>> print ExpensiveClass.numObjects
2
>>> ExpensiveClass.numObjects = 0
>>> z = collections.defaultdict(ExpensiveClass)
>>> print ExpensiveClass.numObjects
0
>>> print z[0]
>>> <__main__.ExpensiveClass object at 0x02566510>
>>> print ExpensiveClass.numObjects
1
Обратите внимание, что вызов x.get
создает новый экземпляр ExpensiveClass
, хотя мы никогда не используем этот экземпляр, потому что x[0]
уже существует.Это может вызвать проблемы, если вы действительно пытаетесь подсчитать количество ExpensiveClass
объектов или если их создание было очень медленным.Эти проблемы не возникают для collections.defaultdict
.