【问题标题】:Data processing in lists with duplicates in PythonPython中具有重复项的列表中的数据处理
【发布时间】:2013-06-05 15:59:01
【问题描述】:

我有两个列表:一个包含产品,另一个包含相关价格。列表可以包含未定义数量的产品。列表示例如下:

  • 产品:['Apple'、'Apple'、'Apple'、'Orange'、'Banana'、'Banana'、'Peach'、'Pineapple'、'Pineapple']
  • 价格:['1.00', '2.00', '1.50', '3.00', '0.50', '1.50', '2.00', '1.00', '1.00']

我希望能够从产品列表中删除所有重复项,并仅保留与价目表中唯一产品相关联的最便宜的价格。请注意,某些产品的价格可能相同(在我们的示例中为菠萝)。

所需的最终列表类似于:

  • 产品:['Apple'、'Orange'、'Banana'、'Peach'、'Pineapple']
  • 价格:['1.00', '3.00', '0.50', '2.00', '1.00']

我想知道在 Python 中最有效的方法。谢谢

【问题讨论】:

    标签: python list duplicates


    【解决方案1】:
    from collections import OrderedDict
    products = ['Apple', 'Apple', 'Apple', 'Orange', 'Banana', 'Banana', 'Peach', 'Pineapple', 'Pineapple']
    prices = ['1.00', '2.00', '1.50', '3.00', '0.50', '1.50', '2.00', '1.00', '1.00']
    
    min_prices = OrderedDict()
    for prod, price in zip(products, prices):
        min_prices[prod] = min(float(price), min_prices.get(prod, float('inf')))
    
    >>> print min_prices.keys(), min_prices.values()
    ['Apple', 'Orange', 'Banana', 'Peach', 'Pineapple'] [1.0, 3.0, 0.5, 2.0, 1.0]
    

    【讨论】:

      【解决方案2】:

      可能最简单的方法是利用字典强制执行唯一键:

      from operator import itemgetter
      Products = ['Apple', 'Apple', 'Apple', 'Orange', 'Banana', 'Banana', 'Peach', 'Pineapple', 'Pineapple']
      Prices = ['1.00', '2.00', '1.50', '3.00', '0.50', '1.50', '2.00', '1.00', '1.00']
      
      final = dict(sorted(zip(Products, Prices), key=itemgetter(1), reverse=True))
      

      【讨论】:

      • 单行编程走得太远了。
      • 我不这么认为;这个比较简单。如果您愿意,您可以将其拆分为存储在变量中的多行,但最终它仍然比创建函数或使用 for 循环或类似的任何东西更简单
      • 我不同意,你的方式要求读者熟悉 dict、zip、sorted、它的 key 和 reverse 可选参数以及 itemgetter。虽然另一个答案使用了尽可能多的标准库符号,但它们大多来自最常用的 20 个核心符号,而 itemgetter 可能不在前 100 个中。更少的字符!= 更具可读性。
      • @morningstar 你不必让你所有的python代码对初学者来说都非常容易阅读,这段代码非常好和可读。我唯一反对的是 O(N log N) 运行时
      • @jamylak 同意效率低下。对于一个简短的列表,我认为它会很好。
      【解决方案3】:

      不是最短的解决方案,但它说明了这一点:假设您的列表分别是 productsprices。那么:

      lookup = dict()    
      for prod, price in zip(products, prices):
          if prod not in lookup:
              lookup[prod] = price
          else:
              lookup[prod] = min(price, lookup[prod])
      

      此时,lookup 字典包含您的每个产品及其最低价格。一个 dict 肯定是比两个列表更好的数据结构;如果你真的想把它作为两个单独的列表,你可以这样做:

      new_prods = []
      new_prices = []
      for prod, price in lookup.items():
          new_prods.append(prod)
          new_prices.append(price)
      

      【讨论】:

        【解决方案4】:

        这个呢:

        prices = map(float,prices)
        r={}
        for k,v in zip(products,prices):
            if v < r.setdefault(k,float('inf')):
                r[k] = v
        products,prices = r.keys(),map(str,r.values())
        

        【讨论】:

        • 你不应该使用sys.maxint使用float('inf')
        【解决方案5】:
        >>> from collections import OrderedDict
        >>> products = ['Apple', 'Apple', 'Apple', 'Orange', 'Banana', 'Banana', 'Peach', 'Pineapple', 'Pineapple']
        >>> prices =  ['1.00', '2.00', '1.50', '3.00', '0.50', '1.50', '2.00', '1.00', '1.00']
        >>> dic = OrderedDict()
        >>> for x,y in zip(products,prices):
        ...     dic.setdefault(x, []).append(y)
        ...     
        >>> dic.keys()
        ['Apple', 'Orange', 'Banana', 'Peach', 'Pineapple']
        >>> [min(val, key = float) for val in dic.values()]
        ['1.00', '3.00', '0.50', '2.00', '1.00']
        

        【讨论】:

          【解决方案6】:

          您可以使用字典来执行此操作:

          Products = ['Apple', 'Apple', 'Apple', 'Orange', 'Banana', 'Banana', 'Peach', 'Pineapple', 'Pineapple']
          Prices = ['1.00', '2.00', '1.50', '3.00', '0.50', '1.50', '2.00', '1.00', '1.00']
          
          Prices=[float(price) for price in Prices]
          
          di={}
          for prod,price in zip(Products,Prices):
              di.setdefault(prod,[]).append(price)
          
          for key,val in di.items():
              di[key]=min(val)
          
          print di
          

          打印{'Orange': 3.0, 'Pineapple': 1.0, 'Apple': 1.0, 'Peach': 2.0, 'Banana': 0.5}

          如果你想要两个列表的顺序相同,你可以这样做:

          from collections import OrderedDict
          
          new_prod=OrderedDict.fromkeys(Products).keys()
          new_prices=[di[item] for item in new_prod]
          

          打印:

          ['Apple', 'Orange', 'Banana', 'Peach', 'Pineapple']
          [1.0, 3.0, 0.5, 2.0, 1.0]
          

          【讨论】:

          • 你的uniq 函数已经过时了,现在的成语是OrderedDict.fromkeys(seq).keys(),它没有使用not seen_add(x) hack
          猜你喜欢
          • 1970-01-01
          • 2011-02-10
          • 2019-10-30
          • 2020-02-06
          • 2021-04-03
          • 2016-01-12
          • 2015-02-25
          • 2016-06-01
          • 1970-01-01
          相关资源
          最近更新 更多