【问题标题】:Compare value in dict with other values将 dict 中的值与其他值进行比较
【发布时间】:2017-10-10 16:40:38
【问题描述】:

我想将 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'],我会收到一个错误,我试图在迭代时修改字典。我看到很多“如何从字典中删除项目”的问题,还有很多关于比较两个单独的字典的问题,但不是这个特定的问题(据我所知)。

编辑
根据 cmets 的反馈,我意识到我的示例有点误导。如果它们的值足够相似,我想合并两个项目。

【问题讨论】:

  • FWIW,我的实际目的是比较两个图像的感知散列,所以代码的语义不如我上面的例子。
  • 您看到了什么错误?您实际上是在迭代字典中项目的笛卡尔积,即对,(key, value)
  • 所以,当您比较 me == other 时,您是在比较 tuple 对象,(key1, value1) == (key2, value2)
  • 请提供您想要的确切输出。应该删除哪个元素?开始的还是结束的?
  • @KaushikNP 这是一个很好的问题,但是没有开始的,也没有结束的dict 对象本质上是无序的。

标签: python dictionary compare


【解决方案1】:

因此,要在线性时间内执行此操作(但需要额外空间),请使用中间 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

【讨论】:

    【解决方案2】:

    请注意,您的结果将取决于遍历的方向。由于您根据距离(在度量意义上)对数据进行分桶,因此右邻居或左邻居都可以声明数据点。

    【讨论】:

    • 确实如此,但在这种情况下,我不在乎哪个值被合并到哪个键中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-25
    • 2022-08-05
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 2016-02-08
    • 1970-01-01
    相关资源
    最近更新 更多