【问题标题】:How to map value to a string in separate lists如何将值映射到单独列表中的字符串
【发布时间】:2020-10-11 15:49:46
【问题描述】:

我正在创建一个函数,该函数按产生的收入最多的顺序返回产品名称。我已经设法获得按正确降序返回成本的功能,但我一直在尝试将价格映射到产品。这是解决这个问题的正确方法吗?

products = ["Computer", "Cell Phones", "Vacuum Cleaner"]
amounts = [3,24,8]
prices = [199,299,399]


def top3(products, amounts, prices):
    totals = []
    items = []
    for item, num1, num2 in zip(products, amounts, prices):
            totals.append(num1 * num2)
            items.append(item)
    return sorted(totals, reverse = True)

【问题讨论】:

  • @Prune OP 付出了巨大的努力,但也遇到了问题。你必须明白,不是每个人都像你一样聪明。
  • 该函数应该返回成本列表还是产品列表?
  • @AnnZen 我对这个问题的解读肯定是他们想要退回产品,但遇到了代码返回成本的问题。

标签: python arrays list mapping


【解决方案1】:

sorted() 与字典一起使用

def top3(products, amounts, prices):
    d = dict(zip(products, zip(amounts, prices)))
    return sorted(d.keys(), key=lambda x: d[x][1] * d[x][0], reverse=True)

【讨论】:

    【解决方案2】:

    我喜欢你的方法。但是,您的代码不会对产品名称进行排序。你可以这样做:

    items = []
    for item, num1, num2 in zip(products, amounts, prices):
            totals.append((item, num1 * num2))
    return sorted(totals, reverse = True)
    

    使用推导的替代解决方案:

    items = [(item, num1 * num2) for item, num1, num2 in zip(products, amounts, prices)]
    return sorted(totals, reverse = True)
    

    【讨论】:

    • 非常感谢Tarik,但我没有提到我只想返回按列表排序的产品名称,不包括价格
    【解决方案3】:

    但我一直在尝试将价格映射到产品

    首先,创建包含产品名称和收入的数据,然后对其进行排序。 Python 中对序列(包括元组和列表)的内置比较功能一次比较一个元素(就像一次比较一个字符一样)。所以:

    totals = sorted(
        [
            (amount * price, name)
            for name, amount, price in zip(products, amounts, prices)
        ],
        reverse=True
    )
    

    您可以看到列表中的每个项目将是收入和名称的一对(2元组);您可以利用这些信息做您需要的事情。

    【讨论】:

      【解决方案4】:

      python 内置集合中的named tuple 是一个被忽视的工具,它可以方便地使这样的代码具有可读性。您可以创建一个轻量级类型,为您提供对象属性等属性,但具有简单元组的存储要求。

      例如,您可以使用以下命令创建 Sales 元组类型:

      Sales = namedtuple('Sales', ('name', 'amount', 'price'))
      
      s = Sales('A Product', 20, 30.99)
      # Sales(name='A Product', amount=20, price=30.99)
      
      s.name
      # 'A Product' 
      

      您可以以一种易于阅读的方式解决您的问题,因为您可以按属性引用属性:

      from collections import namedtuple
      
      Sales = namedtuple('Sales', ('name', 'amount', 'price'))
      
      products = ["Computer", "Cell Phones", "Vacuum Cleaner"]
      amounts = [3,24,8]
      prices = [199,299,399]
      
      sales = [Sales(*item) for item in zip(products, amounts, prices)]
      
      # [Sales(name='Computer', amount=3, price=199),
      #  Sales(name='Cell Phones', amount=24, price=299),
      #  Sales(name='Vacuum Cleaner', amount=8, price=399)]
      
      #get just the names sorted by amount * price
      
      [s.name for s in sorted(sales, key=lambda s: s.price * s.amount, reverse=True)]
      # ['Cell Phones', 'Vacuum Cleaner', 'Computer']
      

      【讨论】:

        【解决方案5】:

        您可以将这三个列表合并为一个包含产品名称和收入的列表。然后从那里,您可以使用sorted() 按产品名称对列表进行排序。有了这个,您还可以通过将lambda x : x[0] 更改为lambda x : x[1] 产生的收入对列表进行排序。这也是假设所有列表的长度相同,并且价格/金额与产品的顺序相同。

        merged = [(products, amounts * price) for products, amounts, price in zip(products, amounts, price)]
        
        total = sorted(merged, key = lambda x : x[0])
        

        【讨论】:

          【解决方案6】:

          在一种或另一种形式中,您将希望将产品和项目一起放入某种集合中,然后使用总计作为排序键但返回名称。

          在每种情况下,sortkey 参数都包含对 函数 的引用,该函数采用正在排序的元素之一并返回用于确定该元素的排序位置的键元素。

          2 元组列表示例。 (item, total)

          def top3(products, amounts, prices):
              item_totals = []
              for item, num1, num2 in zip(products, amounts, prices):
                  item_totals.append((item, num1 * num2))
          
              item_totals.sort(key=lambda t: t[1], reverse=True)
          
              return [t[0] for t in item_totals]
          

          这里,lambda t: t[1] 用于构造一个函数,该函数接受 2 元组并返回第二项,即总数。相当于定义了一个小函数:

          def get_sort_key(t):
              return t[1]
          

          然后传递函数:

              item_totals.sort(key=get_sort_key, reverse=True)
          

          词典列表示例

          为了更好的可读性而不是使用 2 元组列表,我们可以使用带有键 'item''total' 的字典列表:

          def top3(products, amounts, prices):
              item_totals = []
              for item, num1, num2 in zip(products, amounts, prices):
                  item_totals.append({'item': item, 'total': num1 * num2})
          
              item_totals.sort(key=lambda t: t['total'], reverse=True)
          
              return [t['item'] for t in item_totals]
          

          在这种情况下,您可以使用 operator 包中的 itemgetter 来生成可以代替 lambda 的函数。你会使用:

          from operator import itemgetter
          

          然后对sort 的调用可以更改为:

              item_totals.sort(key=itemgetter('total'), reverse=True)
          

          单字典示例

          我们也可以将所有内容放入一个字典中,以乘积为键,以总数为值。但在这种情况下,它依赖于不重复的名称。

          def top3(products, amounts, prices):
              item_totals = {}
              for item, num1, num2 in zip(products, amounts, prices):
                  item_totals[item] = num1 * num2
          
              return sorted(item_totals.keys(),
                            key=lambda item: item_totals[item],
                            reverse=True)
          

          有更紧凑的方法来编写所有这些,这避免了在排序之前构建集合时显式 for 循环的需要,正如其他一些答案所证明的那样,但这是一般原则。

          【讨论】:

            【解决方案7】:

            您可以按照价格从最贵到最便宜的顺序列出每种产品:

            products = ["Computer", "Cell Phones", "Vacuum Cleaner"]
            amounts = [3,24,8]
            prices = [199,299,399]
            
            def top3(prd, amt, prc):
                lst = sorted([(prc, prd) for prd, amt, prc in zip(products, amounts, prices)],reverse = True)
                return [t[1] for t in lst]
            
            print(top3(products, amounts, prices))
            

            输出:

            ['Vacuum Cleaner', 'Cell Phones', 'Computer']
            




            您可以按照以下方式列出每种产品,按照花费从多到少的顺序排列:

            products = ["Computer", "Cell Phones", "Vacuum Cleaner"]
            amounts = [3,24,8]
            prices = [199,299,399]
            
            def top3(prd, amt, prc):
                lst = sorted([(prc*amt, prd) for prd, amt, prc in zip(products, amounts, prices)],reverse = True)
                return [t[1] for t in lst]
            
            print(top3(products, amounts, prices))
            

            输出:

            ['Cell Phones', 'Vacuum Cleaner', 'Computer']
            

            【讨论】:

            • 我知道有数量,但 OP 没有在问题中指定它们
            • @alaniwi 我知道 :)
            猜你喜欢
            • 2013-09-14
            • 1970-01-01
            • 1970-01-01
            • 2016-05-12
            • 2023-03-26
            • 2012-08-21
            • 2021-11-16
            • 1970-01-01
            相关资源
            最近更新 更多