2017-02-21 3 views
0

Я думаю о разных способах взять сумму квадратов в python. Я обнаружил, что следующие работы с использованием списковых:Сумма квадратов с использованием лямбда-функций

def sum_of_squares(n): 
    return sum(x ** 2 for x in range(1, n)) 

Но при использовании лямбда-функции, следующие не вычислить:

def sum_of_squares_lambda(n): 
    return reduce(lambda x, y: x**2 + y**2, range(1, n)) 

Почему это?

+1

что вы имеете в виду под «не вычислить»? – math2001

+2

Поскольку сумма квадратов соответствует лямбда x, y: x + y ** 2', а не 'lambda x, y: x ** 2 + y ** 2'. – hobbs

+1

x + y ** 2 вместо. x - текущая сумма в лямбда, поэтому не повторяйте ее снова. –

ответ

1

Вы должны только квадратировать каждый последующий элемент. x**2 + y**2 квадраты пробега всего (x), а также каждый последующий элемент (y). Измените это на x + y**2, и вы получите правильный результат. Обратите внимание, что, как упоминалось в комментариях, для этого также требуется правильное начальное значение, поэтому вы должны передать 0 в качестве необязательного третьего аргумента.

>>> sum(x ** 2 for x in range(5,15)) 
985 
>>> reduce(lambda x, y: x + y**2, range(5,15)) 
965 
>>> reduce(lambda x, y: x + y**2, range(5,15), 0) 
985 
+1

Использование 'x + y ** 2' будет работать до тех пор, пока последовательность начинается с 1, но она будет терпеть неудачу, если вы попытаетесь распространить ее на произвольные последовательности. – BrenBarn

+0

@BrenBarn - Хорошая точка; исправлено. – TigerhawkT3

2

Подумайте о том, что reduce. Он принимает вывод одного вызова и использует его в качестве первого аргумента при повторном вызове той же функции. Итак, представьте, что n равно 4. Предположим, вы назовете свой лямбда f. Затем вы делаете f(f(1, 2), 3). Это эквивалентно:

(1**2 + 2**2)**2 + 3**2 

Поскольку первый аргумент ваш лямбда квадрат, ваша первая сумма квадратов будет квадрат снова на следующий вызов, а затем эта сумма будет в квадрате снова на следующий, и так на.

+0

Спасибо! Это имеет большой смысл. Так что это почти как рекурсивный вызов для следующих двух элементов итерабельного. –

-2

(для питона 3 пользователей)

from functools import reduce 

Чтобы иметь возможность использовать reduce.

Во-вторых, ваша функция sum_of_squares_lambda не будет работать так, как вы ожидаете, потому что reduce будет принимать дважды (вместо одного) каждый аргумент, кроме первого и последнего.

+1

Если бы я не импортировал правильное сокращение, он бы выбросил ошибку во время выполнения, а не потратил много времени на вычисление. –

+1

'reduce' перешел на' functools' в Python 3. В Python 2 он встроен. –

+0

Да, но я отправил этот ответ перед вашим комментарием ... – math2001

0

Предположим, вы подключаете 4:

1^2 + 2^2 = 5 (you then take this result and put it back in the lambda) 
5^2 + 3^2 = 34 (for reference the correct answer is 14) 

It квадратов "предыдущий" сумму, а в lambda.

(Вы также беловатое по одному вопросу, она должна быть n+1 в вызовах диапазона.)

Смежные вопросы