Подтвердить что ты не робот

В python есть что-то вроде обновленного, чтобы обновить сортировку?

В 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())))

Но я надеялся, что в нем есть что-то, что я уже мог использовать.

4b9b3361

Ответ 1

Вы можете просто использовать встроенный dict():

updated_dict = dict(old_dict, **extra_dict)

Ответ 2

Если вам нужны нестрочные ключи, вы можете использовать такую ​​функцию: (Это не так уродливо, как ваше выражение "на месте" + работает для любого количества словарей)

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()}

Ответ 3

Я не вижу, что неправильно в использовании двух строк, например:

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, я думаю, что это действительно просто вопрос вкуса.