Вот очень простой вопрос о питоническом кодировании.
Учитывая список, если вы хотите рассчитать долю элементов, удовлетворяющих (A и B), из тех, которые удовлетворяют (A), естественным решением будет:
Представьте, что список целых чисел, условие A есть ( > 3), условие B есть ( > 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
Альтернативное решение:
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
Альтернатива выглядит более сексуально для меня, хотя она дважды перебирает элементы и неэффективна. Есть ли приемлемое решение для питона для этого общего сценария или это первое решение достаточно хорошо?
Спасибо.
Ваше (альтернативное) решение отлично, за исключением этого небольшого изменения:
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
Синтаксис, который выглядит как понимание списка без скобок, называется выражением .
Я не знаю ни одного читаемого способа получить решение без повторного перебора по списку дважды, кроме того, который у вас уже есть. Я бы по-прежнему оставил решение выше, если только профайлер не говорит мне, что мне нужно ускорить это.
s = sum(complex(x>3,x>5) for x in items); score = float(s.real)/s.imag
;-)
count = sum(i > 3 for i in items)
Это не общее решение, а одно, основанное на вашем вопросе и ответе образца.
Если вы знаете взаимосвязь между двумя условиями, вам не нужно дважды проходить последовательность:
gt3 = [x for x in items if x > 3]
count = len(gt3)
correct = sum(x > 5 for x in gt3)
Эффективное, более общее и все еще питоническое решение может быть:
count, correct = map(sum, zip(*((x > 3, x > 5) for x in items)))
Условия более 3 и 5 можно заменить любыми другими условиями.
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