Как я могу заставить словарь в python отклонять обновления существующих ключей?

#python #dictionary

#python #словарь

Вопрос:

Возможно ли спроектировать словарь на Python таким образом, чтобы при добавлении по ошибке ключа, который уже есть в словаре, он отклонялся? Спасибо

Комментарии:

1. Я хотел бы отметить, что «уникальные ключи» являются неотъемлемым свойством словаря. Когда вы вставляете пару ключ / значение, она обновляет все предыдущие записи, которые привели бы к дублированию ключей. Поэтому ваш вопрос вызвал у меня цикл for. Теперь, когда я читаю это более внимательно, я понимаю, что вы просите предотвратить такие обновления, что является допустимым и понятным расширением. Я просто хотел прояснить это для других читателей, чтобы они не запутались, думая, что им нужно предотвращать дублирование ключей в более обобщенном смысле.

2. ^ Да, и, как мы видим в приведенном ниже ответе пользователя 2197172, использование ‘setdefault’ является дополнением: оно спокойно проглатывает попытки добавить дубликаты ключей.

3. Я отправил редактирование вопроса, чтобы точно отразить то, что действительно спрашивал пользователь. Теперь это звучит как полезный вопрос (как изменить поведение Python по умолчанию?), а не как полностью избыточный (как заставить Python делать то, что он уже обеспечивает?).

Ответ №1:

Вы всегда можете создать свой собственный словарь

 class UniqueDict(dict):
    def __setitem__(self, key, value):
        if key not in self:
            dict.__setitem__(self, key, value)
        else:
            raise KeyError("Key already exists")
  

Комментарии:

1. Обратите внимание, что __init__ метод на самом деле не нужен, когда он ничего не делает, кроме вызова родительского элемента __init__ с теми же аргументами.

2. Я думаю, что это правильный ответ, но мне не нравится название этого класса. Смотрите мой комментарий к первоначальному вопросу. Может быть, что-то вроде «InsertOnlyDict» или «NoUpdateDict» и т.д. было бы более понятно?

3. Называйте это как хотите. Это действительно не имеет значения. Нет, я не редактирую этот ответ.

4. Возможно ли добавить значение, если ключ уже присутствует. Как и else: dict. __setitem__(self, ключ, self.значение value). Я пытался это сделать, но это просто обновляющее значение.

5. Это все равно проглотит дубликаты ключей, когда они будут переданы конструктору, например, UniqueDict([(‘a’,1),(‘a’, 1)]) возвращает {‘a’: 1}

Ответ №2:

Просто проверьте свой dict перед добавлением элемента

 if 'k' not in mydict:
    mydict.update(myitem)
  

Комментарии:

1. вы можете просто сделать : if 'k' not in mydict без .keys() 🙂

2. @singularity: Вы ДОЛЖНЫ (не можете) избегать .keys() … это грубая трата ресурсов.

3. Извините, это была оплошность. Исправлено в ответе.

Ответ №3:

Это цель setdefault:

 >>> x = {}
>>> print x.setdefault.__doc__
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
>>> x.setdefault('a', 5)
5
>>> x
{'a': 5}
>>> x.setdefault('a', 10)
5
>>> x
{'a': 5}
  

Это также означает, что вы можете пропустить «if ‘key’ в dict: … else: …»

 >>> for val in range(10):
...     x.setdefault('total', 0)
...     x['total'] =val
...
0
0
1
3
6
10
15
21
28
36
>>> x
{'a': 5, 'total': 45}
  

Комментарии:

1. Это милый ответ, и на самом деле дубликаты ключей спокойно проглатываются — это то же самое, что «отклонено», хотя? Исключение не возникает.

2. Вы правы, указав на требование «отклонено», и если это означает выдачу исключения, то это действительно сбой. Я предполагал, что «отклонено» относилось к обновлению значения в dict и не указывало на обработку ошибок.

Ответ №4:

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

Комментарии:

1. @Hossein: в ответе @Jakobs приведен пример.