Установите значение в dict, только если значение еще не установлено
Каков самый pythonic способ установить значение в dict
, если значение еще не установлено?
В настоящий момент мой код использует операторы if:
if "timeout" not in connection_settings:
connection_settings["timeout"] = compute_default_timeout(connection_settings)
dict.get(key,default)
подходит для кода, потребляющего dict, а не для кода, который готовит dict для передачи другой функции. Вы можете использовать его, чтобы установить что-то, но не более красивое imo:
connection_settings["timeout"] = connection_settings.get("timeout", \
compute_default_timeout(connection_settings))
будет вычислять вычислительную функцию, даже если ключ содержал ключ; ошибка.
Defaultdict - это значения по умолчанию одинаковые.
Конечно, вы много раз устанавливаете примитивные значения, которые не нужны для вычислений как значения по умолчанию, и они могут, конечно, использовать dict.setdefault
. Но как насчет более сложных случаев?
Ответы
Ответ 1
Это немного не ответ, но я бы сказал, что самый pythonic - это оператор if, который у вас есть. Вы сопротивлялись стремлению к одному слою с помощью __setitem__
или других методов. Вы избегали возможных ошибок в логике из-за существующих, но-ложных значений, которые могут возникнуть, когда вы пытаетесь быть умными с короткозамкнутым хостом and
/or
. Сразу видно, что функция вычисления не используется, когда она не нужна.
Это ясно, лаконично и читаемо - питоновское.
Ответ 2
dict.setdefault
точно "установит значение в dict, только если значение еще не установлено", что является вашим вопросом. Однако вам все равно нужно вычислить значение, чтобы передать его в качестве параметра, который не является тем, что вы хотите.
Ответ 3
Один из способов сделать это:
if key not in dict:
dict[key] = value
Ответ 4
Я использую следующее, чтобы изменить значения kwargs на значения, отличные от значений по умолчанию, и перейти к другой функции:
def f( **non_default_kwargs ):
kwargs = {
'a':1,
'b':2,
}
kwargs.update( non_default_kwargs )
f2( **kwargs )
Это имеет достоинства, что
Ответ 5
Попробуйте использовать один лайнер:
connection_settings["timeout"] ||= compute_default_timeout(connection_settings)
Ответ 6
Вероятно, вам понадобится dict.setdefault
:
Создайте новый словарь и установите значение:
>>> d = {}
>>> d.setdefault('timeout', 120)
120
>>> d
{'timeout': 120}
Если уже установленное значение, dict.setdefault
не переопределит его:
>>> d['port']=8080
>>> d.setdefault('port', 8888)
8080
>>> d
{'port': 8080, 'timeout': 120}