我可以根据两个值在两个列表上使用reduce和列表推导吗?

3 投票
5 回答
3240 浏览
提问于 2025-04-16 09:05

我有以下这段代码。

sum_review = reduce(add,[book['rw'] for book in books])
sum_rating = reduce(add,[book['rg'] for book in books])
items = len(books)
avg_review = sum_review/items
avg_rating = sum_rating/items

我想要的是这样的结果。

sum_review,sum_rating = reduce(add,([book['rw'],[book['rg']) for book in books])
items = len(books)
avg_review = sum_review/items
avg_rating = sum_rating/items

显然,这样做是不行的。我该如何解决这个重复的问题,而不使用常规的循环呢?

5 个回答

2
sum_review, sum_rating = reduce(lambda a,b: (a[0] + b[0], a[1]+b[1]), ((book['rw'], book['rg']) for book in books), (0,0) )
items = len(books)
avg_review = sum_review/items
avg_rating = sum_rating/items

(已测试)

9

我建议在这里不要使用reduce。对于这么简单的情况,直接用sum就可以了:

sum_review = sum(book['rw'] for book in books)
sum_rating = sum(book['rg'] for book in books)

在我看来,这个简单的版本不需要改动来去掉重复的部分。因为只有两个项目(rwrg),我觉得就这样保持原样最好。

3

简化代码通常有两种常见的方法:

  1. 自上而下:先获取值,然后用 zip(*iterable) 来转置它们。这种方法也很不错,因为它只需要遍历集合一次:

    values = ((book["rw"], book["rg"]) for book in books)
    avg_review, avg_rating = [sum(xs) / len(books) for xs in zip(*values)]
    
  2. 自下而上:创建一个函数来抽象出这个操作:

    get_avg = lambda xs, attr: sum(x[attr] for x in xs) / len(xs)
    avg_review = get_avg(books, "rw")
    avg_rating = get_avg(books, "rg")
    

撰写回答