【问题标题】:Why do keys added to an OrderedDict and sorted inside of a function not stay sorted outside the function?为什么添加到 OrderedDict 并在函数内部排序的键不会在函数外部保持排序?
【发布时间】:2020-06-23 12:27:30
【问题描述】:

我有一个函数,其中包含类似于下面的代码,它接受一个 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']}

为什么排序不保留在函数之外?

【问题讨论】:

  • 当包含函数离开时,对局部变量的更改(通过为其分配另一个对象)将丢失。新创建的 OrderedDict 永远不会转义该函数。只保留对对象本身的更改(例如,当作为参数传递给函数时)。
  • 您的排序字典永远不会“离开功能”。您只是将它分配给一个局部变量,该变量在函数结束时消失。
  • 当您执行ordered_dict = ... 时,您是在本地范围内创建一个新的ordered_dict 变量,而不是修改外部变量。
  • 这能回答你的问题吗? How do I pass a variable by reference?
  • @jasonharper 这完美地回答了我的问题,谢谢!我不知道它会分配为局部变量。

标签: python ordereddict


【解决方案1】:

python 中的变量是对对象的引用。

当你传递参数时,你有两个变量指向同一个对象,一个在函数内部,一个在函数外部。

ordered_dict[new_key] = ["new","list"] 修改现有的 OrderedDict 对象。所以变化在函数之外是可见的。

ordered_dict = OrderedDict(sorted(ordered_dict.items())) 另一方面创建一个新的 OrderedDict 并更改函数中的 ordered_dict 变量以引用它,它对主程序中的 ordered_dict 变量没有影响。

如果您可以使用外部库,您可能需要查看 sortedcontainers 模块。


有没有办法直接作用于传递的变量

不是一个好人。有一个可以使用的“移动到结束”功能,但可能会导致一堆不方便的移动。

我怀疑对 OrderedDict 进行就地排序的最不坏的方法是清空并重新填充它,类似于。

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

不过,Ultimatley 对每个插入都进行完整的处理可能是一个糟糕的设计。如果可用,正确排序的容器可能会执行得更好。

【讨论】:

    【解决方案2】:

    您应该将结果返回到全局范围,而不是修改局部函数范围的变量:

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

    编辑:改变了表述

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-30
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多