Почему ключи, добавленные в OrderedDict и отсортированные внутри функции, не остаются отсортированными вне функции? - PullRequest
1 голос
/ 11 марта 2020

У меня есть функция, которая содержит код, подобный приведенному ниже, который принимает объект OrdredDict и строку в качестве аргументов:

def AddToOrderedDict(ordered_dict, new_key):
    ordered_dict[new_key] = []
    ordered_dict = OrderedDict(sorted(ordered_dict.items()))

Эта функция добавляет ключ в словарь и сортирует его, но не сохранять сортировку после выхода из функции.

Код ниже демонстрирует это поведение:

from collections import OrderedDict

def AddToOrderedDict(ordered_dict, new_key):
    ordered_dict[new_key] = ['New', 'List']
    ordered_dict = OrderedDict(sorted(ordered_dict.items()))
    print(dict(ordered_dict))

ordered_dict = OrderedDict()
ordered_dict['A'] = ['List', 'A']
ordered_dict['C'] = ['List', 'C']
ordered_dict['D'] = ['List', 'D']

AddToOrderedDict(ordered_dict, 'B')

print(dict(ordered_dict))

Вывод:

{'A': ['List', 'A'], 'B': ['New', 'List'], 'C': ['List', 'C'], 'D': ['List', 'D']}
{'A': ['List', 'A'], 'C': ['List', 'C'], 'D': ['List', 'D'], 'B': ['New', 'List']}

Почему сортировка не сохраняется вне функции?

Ответы [ 2 ]

1 голос
/ 11 марта 2020

Переменные в python являются ссылками на объекты.

Когда вы передаете параметр, у вас есть две переменные, указывающие на один и тот же объект, одна внутри функции и одна снаружи.

order_dict [ new_key] = ["new", "list"] изменяет существующий объект OrderedDict. Таким образом, изменение видно за пределами функции.

order_dict = OrderedDict (sorted (order_dict.items ())), с другой стороны, создает новый OrderedDict и изменяет переменную order_dict в функции, чтобы вызывать ее, она имеет не влияет на переменную order_dict в основной программе.

Если вы можете использовать внешние библиотеки, вы можете захотеть взглянуть на модуль sortedcontainers.


Есть ли способ действовать непосредственно на переданную переменную

Не очень хорошая. Существует функция «перейти в конец», которую можно использовать, но она может привести к целому ряду необоснованных перемещений.

Я подозреваю, что наименее плохой способ сортировки OrderedDict на месте - это очистить и пополните его, что-то вроде.

tmp = sorted(ordered_dict.items())
ordered_dict.clear()
ordered_dict.update(tmp)

Ultimatley, хотя, делать полный курорт на каждой вставке, вероятно, плохой дизайн. Правильно отсортированный контейнер, вероятно, будет работать намного лучше, если он доступен.

1 голос
/ 11 марта 2020

Вместо изменения переменной для локальной области действия вы должны вернуть результат в глобальную область:

from collections import OrderedDict

ordered_dict = OrderedDict()

def AddToOrderedDict(ordered_dict, new_key):
    ordered_dict[new_key] = ['New', 'List']
    ordered_dict = OrderedDict(sorted(ordered_dict.items()))
    print(dict(ordered_dict))
    return ordered_dict


ordered_dict['A'] = ['List', 'A']
ordered_dict['C'] = ['List', 'C']
ordered_dict['D'] = ['List', 'D']

ordered_dict = AddToOrderedDict(ordered_dict, 'B')

print(dict(ordered_dict))

edit: изменил формулировку

...