【问题标题】:Extracting unique items from a list of mappings从映射列表中提取唯一项
【发布时间】:2010-09-16 05:07:56
【问题描述】:

他是一个有趣的问题,它正在寻找最 Pythonic 的解决方案。假设我有一个映射列表{'id': id, 'url': url}。列表中的一些 ids 是重复的,我想创建一个新列表,删除所有重复项。我想出了以下功能:

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

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

我想这很有效。但是有没有“更 Pythonic”的方式?或者也许是更有效的方法?

【问题讨论】:

    标签: python unique duplicate-data


    【解决方案1】:

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

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

    虽然这是单行本,但我仍然认为它的可读性很强。

    在使用您的原始解决方案和我的解决方案时,您必须牢记两点:

    • 商品不会始终按照最初的顺序退回
    • 后面的条目将覆盖以前具有相同 id 的条目

    如果您不介意,那么我建议上述解决方案。在其他情况下,此函数保留顺序并优先处理第一次遇到的 id:

    def unique_mapping(mappings):
        addedIds = set()
        for m in mappings:
            mId = m['id']
            if mId not in addedIds:
                addedIds.add(mId)
                yield m
    

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

    【讨论】:

      【解决方案2】:

      有几件事可以改进。

      • 您正在执行两个循环,一个在原始字典上,然后在结果字典上再一次。相反,您可以一步建立结果。

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

      • 仅检查重复项时无需存储值,您可以使用集合代替。

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

      这是一个实现:

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

      【讨论】:

        【解决方案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'}]
        

        【讨论】:

          猜你喜欢
          • 2021-09-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-23
          • 1970-01-01
          相关资源
          最近更新 更多