Ответ 1
Вы можете просто использовать встроенный dict()
:
updated_dict = dict(old_dict, **extra_dict)
В python, если я делаю следующее:
>>> list = [ 3, 2, 1]
>>> sorted_list = k.sort()
Тогда sorted_list
является None
и list
сортируется:
>>> sorted_list = k.sort()
>>> print list, sorted_list
[1, 2, 3] None
Однако, если я делаю следующее:
>>> list = [ 3, 2, 1]
>>> sorted_list = sorted(list)
Затем list
остается несортированным, а sorted_list
содержит копию отсортированного списка:
>>> print list, sorted_list
[3, 2, 1] [1, 2, 3]
Мне интересно, существует ли эквивалент функции update
для словарей.
Таким образом, я мог бы сделать что-то вроде этого:
def foo(a, b, extra={}):
bar = { 'first': a, 'second': b }
special_function(**updated(bar, extra))
normal_function(**bar)
вместо того, чтобы делать что-то вроде этого:
def foo(a, b, extra={}):
bar = { 'first': a, 'second': b }
special_bar = bar.copy()
special_bar.update(extra) # [1]
special_function(**special_bar)
normal_function(**bar)
[1] Да, я понимаю, что я мог бы просто заменить эти две строки на extra.update(bar)
, но предположим, что хочу сохранить extra
, как это было в дальнейшем в функции.
Я понимаю, что могу реализовать это сам:
def updated(old_dict, extra={}):
new_dict = old_dict.copy()
new_dict.update(extra)
return new_dict
Или следующий очень нечитаемый оператор на месте:
special_function(**(dict(bar.items()+extra.items())))
Но я надеялся, что в нем есть что-то, что я уже мог использовать.
Вы можете просто использовать встроенный dict()
:
updated_dict = dict(old_dict, **extra_dict)
Если вам нужны нестрочные ключи, вы можете использовать такую функцию: (Это не так уродливо, как ваше выражение "на месте" + работает для любого количества словарей)
from itertools import chain # ← credits go to Niklas B.
def updated(*dicts):
return dict(chain(*map(dict.items, dicts)))
updated({42: 'the answer'}, {1337: 'elite'}) # {42: 'the answer', 1337: 'elite'}
В противном случае предложение Svens прекрасно.
Изменить: если вы используете Python 2.7 или новее, вы также можете использовать понимание словаря, как предложил Свен в комментариях:
def updated(*dicts):
return {k: v for d in dicts for k, v in d.items()}
Я не вижу, что неправильно в использовании двух строк, например:
new_bar = bar.copy()
new_bar.update(extra)
Он чист и читаем.
>>> d = {1:2, 3:4}
>>> e = {3:9, 5:25}
>>> f = d.copy()
>>> f.update(e)
>>> d
{1: 2, 3: 4}
>>> f
{1: 2, 3: 9, 5: 25}
>>> e
{3: 9, 5: 25}
В трех словах: Zen of Python.
Чтобы быть более ясным: Я хочу сказать, что я бы не заменил эти две строки функцией updated()
, не входящей в стандартную библиотеку.
Если бы мне пришлось споткнуться в строке кода, например:
new_bar = updated(bar, extra)
Мне нужно будет отследить эту функцию, чтобы посмотреть, что она делает. Я не мог доверить, что это не странно.
OP также сравнивал это с sorted()
, но sorted()
имеет смысл существовать, он действует на все, что можно итеративно, и делает это с удивительным timsort. Вместо этого должно быть поведение гипотетического updated()
? Может быть, это метод класса dict
? Это действительно не понятно ИМХО.
Сказано, что можно было выбрать две линии OP, или решение Sven, или выражение понимания/генератора dict, я думаю, что это действительно просто вопрос вкуса.