我希望将dict中的所有条目与所有其他条目进行比较 - 如果值在足够接近的范围内,我想将它们合并到一个键下并删除另一个键。但我无法弄清楚如何在没有错误的情况下迭代dict。
我的代码的示例版本(不是真正的值集,但你明白了):
things = { 'a': 1, 'b': 3, 'c': 22 }
for me in things.iteritems():
for other in things.iteritems():
if me == other:
continue
if abs(me-other) < 5:
print 'merge!', me, other
# merge the two into 'a'
# delete 'b'
我希望得到:
>> { 'a': [ 1, 2 ], 'c': 22 }
但如果我运行此代码,我会得到我要合并的前两个:
>> merge! ('a', 1) ('b', 2)
然后是相反的(我想要合并):
>> duplicate! ('b', 2) ('a', 1)
如果我使用del things['b']
,我会收到一个错误,我试图在迭代时修改dict。我看到很多&#34;如何从字典中删除项目&#34;问题,以及很多关于比较两个单独的词,但不是这个特定的问题(据我所知)。
修改
根据评论中的反馈,我意识到我的例子有点误导。如果它们的值足够相似,我想合并两个项目。
答案 0 :(得分:0)
因此,要在线性时间内执行此操作(但需要额外空间),请使用中间dict
按值对键进行分组:
>>> things = { 'fruit': 'tomato', 'vegetable': 'tomato', 'grain': 'wheat' }
>>> from collections import defaultdict
>>> grouper = defaultdict(list)
>>> for k, v in things.iteritems():
... grouper[v].append(k)
...
>>> grouper
defaultdict(<type 'list'>, {'tomato': ['vegetable', 'fruit'], 'wheat': ['grain']})
然后,您只需将值列表中的第一项(以前是键)作为新键:
>>> {v[0]:k for k, v in grouper.iteritems()}
{'vegetable': 'tomato', 'grain': 'wheat'}
请注意,字典本质上是无序的,因此如果顺序很重要,那么您应该从一开始就使用OrderedDict
。
答案 1 :(得分:0)
请注意,您的结果将取决于遍历的方向。由于您根据距离(在度量标准意义上)对数据进行分段,因此右邻居或左邻居可以声明数据点。