Я хочу вставить пару ключ-значение в dict, если ключ не в dict.keys (). В основном я мог сделать это с помощью:
if key not in d.keys():
d[key] = value
Но есть ли способ лучше? Или каково питоническое решение этой проблемы?
Я хочу вставить пару ключ-значение в dict, если ключ не в dict.keys (). В основном я мог сделать это с помощью:
if key not in d.keys():
d[key] = value
Но есть ли способ лучше? Или каково питоническое решение этой проблемы?
Ответы:
Звонить не нужно d.keys(), поэтому
if key not in d:
d[key] = value
достаточно. Нет более четкого и понятного метода.
Вы можете обновить снова с помощью dict.get(), что вернет существующее значение, если ключ уже присутствует:
d[key] = d.get(key, value)
но я настоятельно не рекомендую этого делать; это игра в код, затрудняющая обслуживание и читаемость.
Использование dict.setdefault():
>>> d = {1: 'one'}
>>> d.setdefault(1, '1')
'one'
>>> d # d has not changed because the key already existed
{1: 'one'}
>>> d.setdefault(2, 'two')
'two'
>>> d
{1: 'one', 2: 'two'}
dict.setdefault()действительно следует использовать только при попытке доступа к значению.
setdefault()четко описывает, что происходит - то, что он также возвращает значение, не так уж и важно, и немного странно ИМО. Не могли бы вы дать быстрое объяснение или ссылку на него, почему это нежелательно?
for obj in iterable: d.setdefault(key_for_obj(obj), []).append(obj). В возвращаемом значении нет ничего необычного, в этом весь смысл метода .
if key not in d:тестом.
setdefault()кажется, что вы ориентируетесь на то, что вы сказали. Использование a defaultdict(list)приведет к более читабельному коду, чем ваш пример ... так что, возможно, он бесполезен, если вам не нужно работать со стандартными словарями. В целом if key not in dпонятнее.
Начиная с Python 3.9 вы можете использовать оператор | слияния для объединения двух словарей. Правый диктант имеет приоритет:
d = { key: value } | d
Примечание: это создает новый словарь с обновленными значениями.
С помощью следующего вы можете вставить несколько значений, а также иметь значения по умолчанию, но вы создаете новый словарь.
d = {**{ key: value }, **default_values}
Я тестировал его с наиболее популярным ответом, и в среднем это происходит быстрее, как это видно в следующем примере.
Тест скорости, сравнивающий метод на основе цикла for с пониманием dict с методом оператора распаковки.
если d = default_vals.copy()в первом случае не выполняется copy ( ), то ответ, получивший наибольшее количество голосов, будет быстрее, когда мы достигнем порядка 10**5и выше. Объем памяти у обоих методов одинаков.
{**default_values, **{ key: value }}
Согласно приведенным выше ответам метод setdefault () работал у меня.
old_attr_name = mydict.setdefault(key, attr_name)
if attr_name != old_attr_name:
raise RuntimeError(f"Key '{key}' duplication: "
f"'{old_attr_name}' and '{attr_name}'.")
Хотя это решение не является универсальным. Как раз меня устроил в этом конкретном случае. Точное решение - проверка keyпервого (как уже было рекомендовано), но setdefault()мы избегаем одного дополнительного поиска в словаре, который хоть и небольшой, но все же дает прирост производительности.