Варианты использования для 'setdefault' dict метод

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

  1. Что setdefault все еще полезный для, сегодня в Python 2.6/2.7?
  2. Какие популярные варианты использования setdefault были заменены с collections.defaultdict?
180
задан Eli Bendersky 14 August 2010 в 02:32
поделиться

3 ответа

Можно сказать, что defaultdict полезен для настроек по умолчанию перед заполнением dict , а setdefault полезен для установки значений по умолчанию во время или после заполнения dict .

Вероятно, наиболее распространенный вариант использования: Группировка элементов (в несортированных данных, иначе используйте itertools.groupby )

# really verbose
new = {}
for (key, value) in data:
    if key in new:
        new[key].append( value )
    else:
        new[key] = [value]


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


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

Иногда вы хотите убедиться, что определенные ключи существуют после создания dict. defaultdict не работает в этом случае, потому что он создает ключи только при явном доступе. Думаю, вы используете что-то в стиле HTTP со многими заголовками - некоторые из них необязательны, но вам нужны значения по умолчанию для них:

headers = parse_headers( msg ) # parse the message, get a dict
# now add all the optional headers
for headername, defaultvalue in optional_headers:
    headers.setdefault( headername, defaultvalue )
193
ответ дан 23 November 2019 в 06:14
поделиться

Я обычно использую setdefault для словарных аргументов аргументов, например, в этой функции:

def notify(self, level, *pargs, **kwargs):
    kwargs.setdefault("persist", level >= DANGER)
    self.__defcon.set(level, **kwargs)
    try:
        kwargs.setdefault("name", self.client.player_entity().name)
    except pytibia.PlayerEntityNotFound:
        pass
    return _notify(level, *pargs, **kwargs)

Он отлично подходит для настройки аргументов в оболочках вокруг функций, которые принимают аргументы ключевого слова.

28
ответ дан 23 November 2019 в 06:14
поделиться

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

Однако интересный вариант использования возникает из стандартной библиотеки (Python 2.6, _threadinglocal.py):

>>> mydata = local()
>>> mydata.__dict__
{'number': 42}
>>> mydata.__dict__.setdefault('widgets', [])
[]
>>> mydata.widgets
[]

Я бы сказал, что использование __ dict __. Setdefault является довольно полезным случаем.

Правка : Как оказалось, это единственный пример в стандартной библиотеке, и он находится в комментарии. Так что, возможно, этого недостаточно, чтобы оправдать существование setdefault . Тем не менее, вот объяснение:

Объекты хранят свои атрибуты в атрибуте __ dict __ . Так получилось, что атрибут __ dict __ доступен для записи в любое время после создания объекта. Это также словарь, а не defaultdict . Для объектов в общем случае неразумно иметь __ dict __ в качестве defaultdict , потому что в этом случае каждый объект будет иметь все допустимые идентификаторы в качестве атрибутов. Поэтому я не могу предвидеть каких-либо изменений в объектах Python, избавляющихся от __ dict __. Setdefault , кроме его полного удаления, если он будет сочтен бесполезным.

5
ответ дан 23 November 2019 в 06:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: