Варианты использования для метода dict 'setdefault' - PullRequest
175 голосов
/ 14 августа 2010

Добавление collections.defaultdict в Python 2.5 значительно уменьшило необходимость в методе dict setdefault. Этот вопрос для нашего коллективного образования:

  1. Для чего все еще полезно setdefault, сегодня в Python 2.6 / 2.7?
  2. Какие популярные варианты использования setdefault были заменены на collections.defaultdict?

Ответы [ 16 ]

1 голос
/ 17 февраля 2016

Другой вариант использования, о котором я не думаю, был упомянут выше. Иногда вы сохраняете в кэше данные объектов по их идентификатору, где основной экземпляр находится в кеше, и вы хотите установить кеш при отсутствии.

return self.objects_by_id.setdefault(obj.id, obj)

Это полезно, когда вы всегда хотите сохранить один экземпляр для каждого отдельного идентификатора, независимо от того, как вы получаете объект каждый раз. Например, когда атрибуты объекта обновляются в памяти и сохранение в хранилище откладывается.

1 голос
/ 25 августа 2015

Я часто использую setdefault, когда получаю это, устанавливая значение по умолчанию (!!!) в словаре; довольно часто словарь os.environ:

# Set the venv dir if it isn't already overridden:
os.environ.setdefault('VENV_DIR', '/my/default/path')

Менее кратко, это выглядит так:

# Set the venv dir if it isn't already overridden:
if 'VENV_DIR' not in os.environ:
    os.environ['VENV_DIR'] = '/my/default/path')

Стоит отметить, что вы также можете использовать результирующую переменную:

venv_dir = os.environ.setdefault('VENV_DIR', '/my/default/path')

Но это менее необходимо, чем это было до существования defaultdicts.

0 голосов
/ 18 апреля 2018

Я переписал принятый ответ и предоставил его новичкам.

#break it down and understand it intuitively.
new = {}
for (key, value) in data:
    if key not in new:
        new[key] = [] # this is core of setdefault equals to new.setdefault(key, [])
        new[key].append(value)
    else:
        new[key].append(value)


# easy with setdefault
new = {}
for (key, value) in data:
    group = new.setdefault(key, []) # it is new[key] = []
    group.append(value)



# even simpler with defaultdict
new = defaultdict(list)
for (key, value) in data:
    new[key].append(value) # all keys have a default value of empty list []

Кроме того, я классифицировал методы как справочные:

dict_methods_11 = {
            'views':['keys', 'values', 'items'],
            'add':['update','setdefault'],
            'remove':['pop', 'popitem','clear'],
            'retrieve':['get',],
            'copy':['copy','fromkeys'],}
0 голосов
/ 17 сентября 2017

Другой вариант использования для setdefault() - , когда вы не хотите перезаписывать значение уже установленного ключа.defaultdict перезаписывает, а setdefault() - нет.Для вложенных словарей чаще всего требуется установить значение по умолчанию только в том случае, если ключ еще не установлен, поскольку вы не хотите удалять текущий вложенный словарь.Это когда вы используете setdefault().

Пример с defaultdict:

>>> from collection import defaultdict()
>>> foo = defaultdict()
>>> foo['a'] = 4
>>> foo['a'] = 2
>>> print(foo)
defaultdict(None, {'a': 2})

setdefault не перезаписывается:

>>> bar = dict()
>>> bar.setdefault('a', 4)
>>> bar.setdefault('a', 2)
>>> print(bar)
{'a': 4}
0 голосов
/ 24 апреля 2017

Мне нравится ответ, приведенный здесь:

http://stupidpythonideas.blogspot.com/2013/08/defaultdict-vs-setdefault.html

Короче говоря, решение (в приложениях, не критичных к производительности) должно приниматься исходя из того, как вы хотитеобрабатывать поиск пустых ключей в нисходящем направлении (, а именно KeyError против значения по умолчанию).

0 голосов
/ 16 марта 2016

[Редактировать] Очень неправильно! Заданная ошибка всегда будет запускать long_computation, с нетерпением Python.

Расширение ответа Таттла.Для меня лучшим вариантом использования является механизм кэширования.Вместо:

if x not in memo:
   memo[x]=long_computation(x)
return memo[x]

, который занимает 3 строки и 2 или 3 поиска, я бы с радостью написал: :

return memo.setdefault(x, long_computation(x))
...