如何解决是否可以交换有序字典的两个键?
注意:我使用的是 python 3.8.2,所以字典被认为是有序的
我正在创建一棵二叉树,并使用字典对树进行建模。
例如:
{1:[2,3],2:[4,5],3:[],4:[],5:[]}
在这个例子中,上面的树看起来像这样:
1
/ \
2 3
/ \
4 5
我试图模拟一些节点的“上升”,并保持字典的顺序。
我知道使用 myDict[key1],myDict[key2] = myDict[key2],myDict[key1]
不起作用,因为 值 的位置发生了变化,而不是键。
我还考虑使用 .popitem()
删除最后一个值,直到我到达 key1 或 key2,然后继续直到到达另一个键,但这似乎有点困难。有没有其他方法可以做到这一点?
解决方法
由于您只想交换两个密钥,我们可以从以下代码开始:
>>> changedDict = {}
>>> for key,value in myDict.items():
... if key not in (key1,key2):
... changedDict[key] = value
然后继续如下:
... elif key == key1:
... changedDict[key] = myDict[key2]
... else:
... changedDict[key] = myDict[key1]
,
字典,虽然它们现在保持插入顺序,否则不能任意排序。如果你真的想使用字典顺序信息来构建你的树,我认为唯一可靠的方法是构建一个新的字典,为这些交换操作中的每一个复制原始字典的内容。
如果您想要一个任意排序的字典,更合理的方法是继承 collections.abc.MutableMapping
并使用字典和其他一些数据结构(例如列表)跟踪该对象内的数据。
这听起来可能很复杂,但可能比您想象的要简单:
from collections.abc import MutableMapping
class SuperOrdered(MutableMapping):
def __init__(self):
self.data = {}
self.order = []
def __setitem__(self,key,value):
if key not in self.data:
self.order.append(key)
self.data[key] = value
def __getitem__(self,key):
return self.data[key]
def __delitem__(self,key):
del self.data[key]
self.order.remove(key)
def __len__(self):
return len(self.data)
def __iter__(self):
yield from iter(self.order)
def replace_key(self,oldkey,newkey,value):
if newkey in self.data:
del self[newkey]
position = self.order.index(oldkey)
self.order[position] = newkey
self.data[newkey] = value
def __repr__(self):
return f"{self.__class__.__name__}({{{','.join(repr(key) + ':' + repr(self.data[key]) for key in self)}}})"
瞧——映射+“replace_key”方法应该足以让你在思考时构建你的树。
这是上面交互式提示中的类:
In [18]: aa = SuperOrdered()
In [19]: aa["a"] = 1;aa["b"] = 2;aa["c"] = 3
In [20]: aa
Out[20]: SuperOrdered({'a':1,'b':2,'c':3})
In [21]: aa.replace_key("a","d",4)
In [22]: aa
Out[22]: SuperOrdered({'d':4,'c':3})
除了这个答案,主题之外:如果你想检查一个我希望“生产就绪”的树实现,我已经发布了一个作为我的 extradict 包(pip 可安装)的一部分。
update:还可以从 collections.OrderedDict
继承并在那里添加 replace_key
方法。该代码必须处理 OrderedDict 内部结构,但这并不难。
外部链接: Github modification
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。