我有以下代码。
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
显然这不起作用。如果没有常规循环,我怎样才能解决这种冗余?
答案 0 :(得分:9)
我在这里避免使用reduce。对于这么简单的使用sum
:
sum_review = sum(book['rw'] for book in books)
sum_rating = sum(book['rg'] for book in books)
在我看来,这个更简单的版本不需要重构来删除冗余。只有两个项目(rw
和rg
)我认为最好保持原样。
答案 1 :(得分: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")
答案 2 :(得分:2)
您应该优先考虑清晰度而不是优化。在使用Python的3年中,我只需要分析两次发现性能瓶颈。您的原始代码清晰有效。将前两行压缩为一个会损害可读性并且几乎不会影响性能。
如果我有来修改你的代码,它会这样:
avg_review = sum(book['rw'] for book in books) / len(books)
avg_rating = sum(book['rg'] for book in books) / len(books)
(这是五行代码,一到两行,提高了清晰度。)
答案 3 :(得分:1)
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
(测试)
答案 4 :(得分:1)
如何解决此冗余问题
通过制作一个功能,当然:
def average_value(items, key):
values = [x[key] for x in items]
return sum(items) / len(items)
avg_review, avg_rating = average_value(books, 'rw'), average_value(books, 'rg')