开发者

Pythonic proportion calculation of two conditions

开发者 https://www.devze.com 2023-02-06 02:21 出处:网络
Here\'s a really simple question regarding pythonic coding. Given a list, if you want to calculate the proportion of items satisfying (A and B), out of those satisfying (A), a natural solution would

Here's a really simple question regarding pythonic coding.

Given a list, if you want to calculate the proportion of items satisfying (A and B), out of those satisfying (A), a natural solution would be:

Imagine the list is of integers, condition A is (>3), condition B is (>5)

count = 0
correct = 0

for item in items:
  if item > 3:
    count += 1

    if item > 5:
      correct += 1

score = float(correct) / count
print '%.2f' % score

An alternative solution:

count = len([1 for i in items if i > 3])
correct = len([1 for i in items if i > 5])

score = float(correct) / count
print '%.2f' % score

The altern开发者_如何学运维ative looks sexier to me, though it loops through items twice and is not efficient. Is there an accepted pythonic solution to this common scenario or is the first solution good enough?

Thanks.


Your (alternate) solution is great, except for this small change:

count = sum(1 for i in items if i > 3)
correct = sum(1 for i in items if i > 5)

score = float(correct) / count
print '%.2f' % score

The syntax that looks like a list comprehension without the brackets is called a generator expression.

I'm not aware of any readable way to get a solution without iterating over the list twice, other than the one you already have. I'd still go with the solution above, unless a profiler tells me I have to speed this up.


This is not a general solution, but one based on your question and the sample answer.

If you know the relationship between the two conditions, then you don't have to traverse the sequence twice:

gt3 = [x for x in items if x > 3]
count = len(gt3)
correct = sum(x > 5 for x in gt3)

An efficient, more general, and still pythonic solution could be:

count, correct = map(sum, zip(*((x > 3, x > 5) for x in items)))

The conditions of greater than 3 and 5 can be replaced by any other conditions.


from itertools import groupby
li={x:len(list(y))for x,y in groupby(l,lambda x:2 if x>5 else 1 if x>3 else 0)}
print(li[2]/(li[1]+li[2]))

python3.1

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号