如何在不同列表中将值映射为字符串

3
我正在创建一个函数,按照收入最高的顺序返回产品名称。我已经成功让函数以正确的降序返回成本,但是我在尝试将价格映射到产品时遇到了问题。这是解决问题的正确方法吗?
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)

6
OP已经付出了很大的努力,但遇到了问题。你需要理解并不是每个人都像你那么聪明。 - Tarik
1
该函数应该返回成本列表还是产品列表? - Ann Zen
2
@AnnZen 我理解这个问题的意思是他们“想要”退货,但是遇到了代码返回成本的问题。 - alani
7个回答

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)

1

我喜欢你的方法。然而,你的代码无法对产品名称进行排序。你可以这样做:

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。但是我没有提到我只想返回按列表排序的产品名称,不包括价格。 - pizza123

0
但是我在尝试将价格映射到产品时遇到了困难。
首先,创建包含产品名称和收入的数据,然后对其进行排序。Python中序列(包括元组和列表)的内置比较会逐个元素进行比较(就像字符串一样逐个字符进行比较)。所以:
totals = sorted(
    [
        (amount * price, name)
        for name, amount, price in zip(products, amounts, prices)
    ],
    reverse=True
)

你可以看到列表中的每个项都是一个收入和名称的一对(2元组);你可以根据需要使用这些信息。


0

Python内置的collections中的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']

0

以下是你可以做的,按照价格从高到低列出每个产品的方法:

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在问题中没有明确指定。 - Ann Zen
@alaniwi 我知道 :) - Ann Zen

0

在某种形式下,您将想要将产品和项目组合成某种集合,然后使用总数作为排序的关键字,但返回名称。

在每种情况下,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)

带有字典列表的示例

为了更好的可读性,我们可以使用一个包含键'item''total'的字典列表,而不是使用一个由2元组组成的列表:

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循环,正如其他答案所示,但这是一般原则。


0
你可以将这三个列表合并成一个包含产品名称和收入的列表。然后,你可以使用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])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接