从映射列表中提取唯一项

2024-04-25 03:53:52 发布

您现在位置:Python中文网/ 问答频道 /正文

他是一个有趣的问题,寻找最具Python式的解决方案。假设我有一个映射列表{'id': id, 'url': url}。列表中的一些id是重复的,我想创建一个新列表,删除所有重复项。我想出了以下函数:

def unique_mapping(map):
    d = {}
    for res in map:
        d[res['id']] = res['url']

    return [{'id': id, 'url': d[id]} for id in d]

我想这是相当有效的。但有没有一种“更像Python”的方式呢?或者更有效的方法?在


Tags: 方法函数inidurlmap列表for
3条回答

我认为这可以变得更简单。字典不允许有重复的键。将映射列表放入映射字典中。这将删除重复项。在

>>> someListOfDicts= [
    {'url': 'http://a', 'id': 'a'}, 
    {'url': 'http://b', 'id': 'b'}, 
    {'url': 'http://c', 'id': 'a'}]

>>> dict( [(x['id'],x) for x in someListOfDicts ] ).values()

[{'url': 'http://c', 'id': 'a'}, {'url': 'http://b', 'id': 'b'}]

有几件事你可以改进。在

  • 你要执行两个循环,一个在原始dict上,然后在result dict上,你可以用一个步骤来构建结果。

  • 您可以改为使用生成器,以避免预先构建整个列表。(如果需要,使用list(unique_mapping(items))将其转换为完整列表)

  • 当只检查重复项时,不需要存储该值,可以使用set代替。

  • 您将为每个元素重新创建字典,而不是返回原始元素。这可能实际上是需要的(例如,您正在修改它们,并且不想接触原始字典),但如果不需要,则使用已经创建的词典会更有效。

下面是一个实现:

def unique_mapping(items):
    s = set()
    for res in items:
        if res['id'] not in s:
            yield res
            s.add(res['id'])

您的示例可以稍微重写一下,以使用生成器表达式构造第一个字典,并消除构造另一个映射的必要性。重复使用旧的:

def unique_mapping(mappings):
    return dict((m['id'], m) for m in mappings).values()

虽然这只是一句话,但我仍然认为它是相当可读的。在

当你在使用我的解决方案时,请记住:

  • 这些项目不会总是按原来的顺序返回
  • 后面的条目将用相同的id覆盖以前的条目

如果你不介意的话,我建议上面的解决方案。在另一种情况下,此函数将保留顺序并优先处理第一次遇到的ID:

^{pr2}$

如果需要列表而不是生成器,则可能需要用list(unique_mappings(mappings))调用它。在

相关问题 更多 >