【问题标题】:Remove duplicate entries from nested dictionary, if two values are the same, in Python如果两个值相同,则在 Python 中从嵌套字典中删除重复条目
【发布时间】:2010-11-05 10:11:09
【问题描述】:

考虑这种字典格式。

{1:{'name':'chrome', 'author':'google', 'url':'http://www.google.com/' },
 2:{'name':'firefox','author':'mozilla','url':'http://www.mozilla.com/'}}

我想删除所有具有相同名称和作者的项目。

我可以通过将所有键放在一个集合中轻松地删除基于键的重复条目,并且可以扩展它以处理特定值,但这似乎是一个昂贵的操作,它会多次迭代字典。我不知道如何以有效的方式使用两个值来做到这一点。这是一本包含数千个项目的字典。

【问题讨论】:

  • 你如何获得这些数据?您可以首先使用到 URL 的字典映射(名称、作者)对来构建它,然后根本不需要这样做。
  • 可能只是改变了字典的结构并设置了名字和作者是字典的关键吗?
  • 我没有特别提到,但我也想统计删除的项目以供内部参考,通过前后执行len(dict)。改变结构没有区别,因为我也删除了重复的键。我稍微简化了示例中的字典。

标签: python dictionary python-2.5


【解决方案1】:

遍历字典,随时跟踪遇到的(name, author) 元组并删除已经遇到的元组:

def remove_duplicates(d):
    encountered_entries = set()
    for key, entry in d.items():
        if (entry['name'], entry['author']) in encountered_entries:
            del d[key]
        else:
            encountered_entries.add((entry['name'], entry['author']))

【讨论】:

  • d.keys() 上迭代时不允许更改字典——这会给出未定义的结果。
  • @Sven:在 Python 2.5 中迭代 d.keys() 并更改字典是可以的(这个问题是关于这个的)。 d.keys() 返回 dict 中的键列表,该列表不受 dict 后续修改的影响。但是,在迭代字典本身或 d.iterkeys()d.itervalues()d.iteritems() 时修改字典是不行的。
  • @Pär:你是对的 :) 我总是使用iterkeys() 来避免中间列表。
  • 您可以将循环更改为for key, entry in d.items(): 以节省一行:)
【解决方案2】:

让我们看看这是否有效......

from itertools import groupby

def entry_key(entry):
    key, value = entry
    return (value['name'], value['author'])

def nub(d):
    items = d.items()
    items.sort(key=entry_key)
    grouped = groupby(items, entry_key)
    return dict([grouper.next() for (key, grouper) in grouped])

【讨论】:

  • 我试过了,但是 Python 2.5 没有next()。也许我应该把它放在文本中,而不仅仅是一个标签。
  • 哦,好的。只需使用 .next() 即可。
  • 谢谢,它有效。但是我已经对其进行了分析,而另一个答案大约是原来的两倍。
猜你喜欢
  • 1970-01-01
  • 2018-04-14
  • 2019-09-08
  • 2021-02-23
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 2017-07-04
  • 2014-01-28
相关资源
最近更新 更多