我可以根据两个值在两个列表上使用reduce和列表推导吗?
我有以下这段代码。
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)
在我看来,这个简单的版本不需要改动来去掉重复的部分。因为只有两个项目(rw
和rg
),我觉得就这样保持原样最好。
3
简化代码通常有两种常见的方法:
自上而下:先获取值,然后用
zip(*iterable)
来转置它们。这种方法也很不错,因为它只需要遍历集合一次:values = ((book["rw"], book["rg"]) for book in books) avg_review, avg_rating = [sum(xs) / len(books) for xs in zip(*values)]
自下而上:创建一个函数来抽象出这个操作:
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")