Defaultdict со значением по умолчанию 1?

Я новичок в python, и я прочитал фрагмент кода из какого-то места. Это реализация подсчета сортировки.

Код выглядит следующим образом:

from collections import defaultdict
def sort_colors(A):
    ht = {}                        # a hash map
    ht = defaultdict(lambda:0, ht) # with default value 1
    for i in A:
         ht[i] += 1
    ret = []
    for k in [0, 1, 2]:
        ret.extend([k]*ht[k])
    return ret

Как и в первых двух строках func, это

ht = {}
ht = defaultdict(lambda:0, ht)

Я не совсем понимаю эту инициализацию. Не могли бы вы помочь мне разобраться? а также, просто заменим ли эти две строки следующим?

ht = defaultdict(int) # default value 0

Ответы

Ответ 1

ht = {}
ht = defaultdict(lambda:0, ht)

defaultdict отличаются от dict тем, что при попытке доступа к регулярному dict с ключом, который не существует, он вызывает KeyError.
defaultdict, однако, doesn 't вызывает ошибку: вместо этого он создает ключ для вас. С какой ценностью? С возвратом callabe вы передали в качестве аргумента. В этом случае каждый новый ключ будет создан со значением 0 (который является возвратом простой функции lambda lambda:0), что также является тем же возвратом int(), поэтому в в этом случае не было бы никакой разницы в изменении функции по умолчанию на int().

Более подробная разбивка этой строки: ht = defaultdict(lambda:0, ht)

Первый аргумент - это функция, которая является вызываемым объектом. Это функция, которая будет вызываться для создания нового значения для несуществующего ключа. Второй аргумент ht является необязательным и относится к базовому словарю, в который будет встроен новый defaultdict. Поэтому, если ht имел некоторые ключи и значения, defaultdict также имел бы эти ключи с соответствующими значениями. Если вы попытаетесь получить доступ к этим ключам, вы получите старые значения. Однако, если вы не пройдете базовый словарь, будет создан новый defaultdict, и, таким образом, все новые ключи, к которым обратились бы, получат значение по умолчанию, возвращаемое из вызываемого.
(В этом случае, поскольку ht изначально пуст dict, при выполнении ht = defaultdict(lambda:0), ht = defaultdict(int) или ht = defaultdict(lambda:0, ht) не было бы никакой разницы: все они будут строить одинаковые defaultdict.

Ответ 2

Я думаю, вы можете просто передать лямбда-функцию, которая возвращает 1

d = defaultdict(lambda:1)