我可以根据两个值将列表理解减少到两个列表吗?

时间:2022-10-30 10:19:24

I've got the following code.

我有以下代码。

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

What I'd like is this.

我想要的是这个。

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

Obviously this doesn't work. How can I solve this redundancy, without a regular loop?

显然这不起作用。如果没有常规循环,我该如何解决这种冗余?

5 个解决方案

#1


3  

There are two typical approaches to simplify code:

有两种简化代码的典型方法:

  1. Top-down: get the values first and then transpose them with zip(*iterable). It's also cool because it only iterates the collection once:

    自上而下:首先获取值,然后使用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. Bottom-up: create a function to abstract the operation:

    自下而上:创建一个抽象操作的函数:

    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


9  

I'd avoid using reduce here. For something so simple use sum:

我在这里避免使用reduce。对于这么简单的东西总和:

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

In my opinion this simpler version doesn't need refactoring to remove redundancy. With just two items (rw and rg) I think it's best to just leave it as it is.

在我看来,这个更简单的版本不需要重构来删除冗余。只有两个项目(rw和rg)我认为最好保持原样。

#3


2  

You should prefer clarity over optimization. In 3 years of using Python, I have only had to profile to discover performance bottlenecks twice. Your original code is clear and efficient. Compressing the first two lines into one hurts readability and barely impacts performance.

您应该更倾向于优化清晰度。在使用Python的3年中,我只需要进行配置文件以发现性能瓶颈两次。您的原始代码清晰有效。将前两行压缩为一个会损害可读性并且几乎不会影响性能。

If I had to revise your code, it would like this:

如果我必须修改你的代码,它会喜欢这个:

avg_review = sum(book['rw'] for book in books) / len(books)
avg_rating = sum(book['rg'] for book in books) / len(books)

(That's five lines of code down to two with an improvement of clarity.)

(这是五行代码,下降到两行,提高了清晰度。)

#4


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

(tested)

(测试)

#5


1  

How can I solve this redundancy

我该如何解决这种冗余问题

By making a function, of course:

通过制作一个功能,当然:

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')

#1


3  

There are two typical approaches to simplify code:

有两种简化代码的典型方法:

  1. Top-down: get the values first and then transpose them with zip(*iterable). It's also cool because it only iterates the collection once:

    自上而下:首先获取值,然后使用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. Bottom-up: create a function to abstract the operation:

    自下而上:创建一个抽象操作的函数:

    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


9  

I'd avoid using reduce here. For something so simple use sum:

我在这里避免使用reduce。对于这么简单的东西总和:

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

In my opinion this simpler version doesn't need refactoring to remove redundancy. With just two items (rw and rg) I think it's best to just leave it as it is.

在我看来,这个更简单的版本不需要重构来删除冗余。只有两个项目(rw和rg)我认为最好保持原样。

#3


2  

You should prefer clarity over optimization. In 3 years of using Python, I have only had to profile to discover performance bottlenecks twice. Your original code is clear and efficient. Compressing the first two lines into one hurts readability and barely impacts performance.

您应该更倾向于优化清晰度。在使用Python的3年中,我只需要进行配置文件以发现性能瓶颈两次。您的原始代码清晰有效。将前两行压缩为一个会损害可读性并且几乎不会影响性能。

If I had to revise your code, it would like this:

如果我必须修改你的代码,它会喜欢这个:

avg_review = sum(book['rw'] for book in books) / len(books)
avg_rating = sum(book['rg'] for book in books) / len(books)

(That's five lines of code down to two with an improvement of clarity.)

(这是五行代码,下降到两行,提高了清晰度。)

#4


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

(tested)

(测试)

#5


1  

How can I solve this redundancy

我该如何解决这种冗余问题

By making a function, of course:

通过制作一个功能,当然:

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')