Как добавить или увеличить словарный запас?
В настоящее время я снова общаюсь с Python после долгого отсутствия и люблю его. Тем не менее, я нахожу, что снова нахожусь на картине. Я продолжаю думать, что должен быть лучший способ выразить то, что я хочу, и что, вероятно, я ошибаюсь.
Код, который я пишу, имеет следующий вид:
# foo is a dictionary
if foo.has_key(bar):
foo[bar] += 1
else:
foo[bar] = 1
Я пишу это много в своих программах. Моя первая реакция заключается в том, чтобы вытолкнуть ее на вспомогательную функцию, но так часто библиотеки python поставляют такие вещи уже.
Есть ли какой-то простой синтаксический трюк, который мне не хватает? Или это так, как это должно быть сделано?
Ответы
Ответ 1
Используйте defaultdict
:
from collections import defaultdict
foo = defaultdict(int)
foo[bar] += 1
В Python >= 2.7 у вас также есть отдельный класс Counter для этих целей. Для Python 2.5 и 2.6 вы можете использовать его backported version.
Ответ 2
Метод dict
get()
принимает необязательный второй параметр, который может использоваться для предоставления значения по умолчанию, если запрошенный ключ не является найдено:
foo[bar] = foo.get(bar, 0) + 1
Ответ 3
Я провел некоторое время. Довольно много. Однако однострочная команда .get()
выполняется быстрее.
Вывод:
get 0.543551800627
exception 0.587318710994
haskey 0.598421703081
код:
import timeit
import random
RANDLIST = [random.randint(0, 1000) for i in range(10000)]
def get():
foo = {}
for bar in RANDLIST:
foo[bar] = foo.get(bar, 0) + 1
def exception():
foo = {}
for bar in RANDLIST:
try:
foo[bar] += 1
except KeyError:
foo[bar] = 1
def haskey():
foo = {}
for bar in RANDLIST:
if foo.has_key(bar):
foo[bar] += 1
else:
foo[bar] = 1
def main():
print 'get', timeit.timeit('get()', 'from __main__ import get', number=100)
print 'exception', timeit.timeit('exception()', 'from __main__ import exception', number=100)
print 'haskey', timeit.timeit('haskey()', 'from __main__ import haskey', number=100)
if __name__ == '__main__':
main()
Ответ 4
Для Python >= 2.5 вы можете сделать следующее:
foo[bar] = 1 if bar not in foo else foo[bar]+1
Ответ 5
Вы также можете воспользоваться структурой управления при обработке исключений. Исключение KeyError
генерируется словарем при попытке присвоить значение несуществующему ключу:
my_dict = {}
try:
my_dict['a'] += 1
except KeyError, err: # in 2.6: `except KeyError as err:`
my_dict['a'] = 1