Заменить defaultdict коллекций обычным dict на setdefault - PullRequest
0 голосов
/ 31 октября 2019

Я часто использовал collections.defaultdict, чтобы иметь возможность добавить элемент к d[key] без необходимости сначала инициализировать его как [] (преимущество: вам не нужно делать: if key not in d: d[key] = []):

import collections, random
d = collections.defaultdict(list)  
for i in range(100):
    j = random.randint(0,20)
    d[j].append(i)  # if d[j] does not exist yet, initialize it to [], so we can use append directly

Теперь я понимаю, что мы можем просто использовать обычные dict и setdefault:

import random
d = {}
for i in range(100):
    j = random.randint(0,20)
    d.setdefault(j, []).append(i)

Вопрос: при использовании dict, значения которого являются списками, есть лихорошая причина использовать collections.defaultdict вместо второго метода (используя простые dict и setdefault), или они чисто эквивалентны?

Ответы [ 3 ]

2 голосов
/ 31 октября 2019

collections.defaultdict, как правило, более производительный, он оптимизирован именно для этой задачи и реализован на C. Однако вы должны использовать dict.setdefault, если хотите, чтобы доступ к отсутствующему ключу в полученном словаре приводил к KeyError, а не к вставке пустого списка. Это самое важное практическое отличие.

1 голос
/ 31 октября 2019

При использовании defaultdict у вас есть возможность сделать добавление на месте:

import collections, random
d = collections.defaultdict(list)  
for i in range(100):
    j = random.randint(0,20)
    d[j] += [i]

Не существует эквивалентной конструкции, такой как d.setdefault(j, []) += [i], она дает SyntaxError: cannot assign to function call.

1 голос
/ 31 октября 2019

В дополнение к ответу Chris_Rands я хочу еще раз подчеркнуть, что основной причиной использования defaultdict является то, что вы хотите, чтобы доступ к ключу всегда выполнялся успешно, и вставьте значение по умолчанию, если его не было. Это может быть по любой причине, и вполне допустимым является удобство возможности использовать [] вместо необходимости вызывать dict.setdefault перед каждым доступом.

Также обратите внимание, что key in default_dict все равно вернетсяFalse если к этому ключу никогда не обращались ранее, то вы все равно можете проверить наличие ключей в defaultdict, если это необходимо. Это позволяет добавлять списки, не проверяя их существование, а также проверяя наличие списков, если это необходимо.

...