Как добавить или увеличить словарную статью? - PullRequest
55 голосов
/ 13 апреля 2010

В настоящее время я снова общаюсь с Python после долгого отсутствия и люблю его. Тем не менее, я снова и снова сталкиваюсь с паттернами. Я продолжаю думать, что должен быть лучший способ выразить то, что я хочу, и что я, вероятно, делаю это неправильно.

Код, который я пишу, имеет следующий вид:

# foo is a dictionary
if foo.has_key(bar):
  foo[bar] += 1
else:
  foo[bar] = 1

Я много пишу в своих программах. Моя первая реакция состоит в том, чтобы передать это вспомогательной функции, но так часто библиотеки Python уже предоставляют такие вещи.

Есть какой-то простой синтаксический трюк, который я пропускаю? Или это так, как это должно быть сделано?

Ответы [ 5 ]

94 голосов
/ 13 апреля 2010

Метод dict get() принимает необязательный второй параметр, который можно использовать для предоставления значения по умолчанию, если запрошенный ключ не найден:

foo[bar] = foo.get(bar, 0) + 1
94 голосов
/ 13 апреля 2010

Используйте defaultdict:

from collections import defaultdict

foo = defaultdict(int)
foo[bar] += 1

В Python> = 2.7 у вас также есть отдельный класс Counter для этих целей. Для Python 2.5 и 2.6 вы можете использовать версию с обратным портом .

5 голосов
/ 13 апреля 2010

Я провел некоторое сравнение времени. Почти равный. Однако однострочная команда .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()
3 голосов
/ 13 апреля 2010

Вы также можете воспользоваться преимуществами структуры управления при обработке исключений. KeyError исключение выдается словарем при попытке присвоить значение несуществующему ключу:

my_dict = {}
try:
    my_dict['a'] += 1
except KeyError, err:    # in 2.6: `except KeyError as err:`
    my_dict['a'] = 1
3 голосов
/ 13 апреля 2010

Для Python> = 2.5 вы можете сделать следующее:

foo[bar] = 1 if bar not in foo else foo[bar]+1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...