Python lambda function - python

What is happening here?
reduce(lambda x,y: x+y, [x for x in range(1,1000) if x % 3 == 0 or x % 5 == 0])
I understand how x is iterating through all of the numbers from 1 to 999 and taking out those that are divisible by 3 or 5, but the 'lambda x,y: x+y' part is stumping me.

This is bad Python for
sum(x for x in range(1,1000) if x % 3 == 0 or x % 5 == 0)
It simply sums all numbers in the range 1..999 divisible by 3 or 5.
reduce() applies the given function to the first two items of the iterable, then to the result and the next item of the iterable, and so on. In this example, the function
lambda x, y: x + y
simply adds its operands.

saying
f = lambda x, y : x + y
is almost the same as saying
def f(x, y):
return x + y
in other words lambda returns a function that given the parameters to the left of the : sign will return the value of the expression on the right of it.
In respect to a function is however quite limited, for example allows only one expression and no statements are allowed. This is not a serious problem however because in Python you can define a full function even in the middle of another function and pass that instead.
The usage you shown is however quite bad bacause a lambda there is pointless... Python would allow to compute that sum directly instead of using reduce.
Also, by the way, for the result of that computation there is an easy closed-form solution that doesn't require any iteration at all... (hint: the sum of all numbers from 1 to n is n*(n+1)/2 and the sum of all multiples of 5 from 5 to n is 5*(sum of all numbers from 1 to n/5) ... therefore ...)

A lambda designates an anonymous function. The syntax lambda x,y: x+y can be stated in English as "declare a nameless function taking two parameters named x and y. Perform the operation x+y. The return value of this nameless function will by the result of this operation"
reduce applies some function sequentially to the first two elements of a supplied list, then to the result of that function and the third element, and so on. Therefore, the lambda in the supplied code is used by reduce to add together the elements of the supplied list, which will contain all of the multiples of 3 and 5 less than 1000.

Related

Python recursive function definition storage issue

I am trying to get a list of functions defined recursively by storing each step of a math serie:
x^0+x^1+x^2+x^3+... → f0(x)=1, f1(x)=1+x, f2(x)=1+x+x², f3(x)=1+x+x²+x³, ...
I coded this in python:
n = 3
devs = [lambda x: 1]
for k in range(n):
devs.append(lambda x, f=devs[k]: f(x) + x**(k+1))
print(devs[-1](4)) # x=4
I learned in this answer that you need to pass the previous function as default argument in order to solve the maximum recursion depth error, but this outputs 193.
I think it has to do with the k in the default parameter. It seems to calculate: 1+4^3+4^3+4^3=193, or more accurately 1+n*x^n instead of x^0+x^1+...+x^n
Can you please tell me what am I doing wrong here?
I think the same question you linked has the answer to your problem. Because the k inside the function is evaluated only outside the loop, it will have the last value from the loop. You can check the documention for how it works in depth.
The correct code is
n = 4
devs = [lambda x: 1]
for k in range(n):
devs.append(lambda x, f=devs[k], j=k: f(x) + x**(j+1))
One liner just for fun!
n=10
devs = (lambda f:[f] + [f := (lambda x, a=k, g=f: g(x) + x**(a+1)) for k in range(n)])(lambda x:1)

Python Recursion without While loop and find remainder of x/y without using %operators?

Not sure what went wrong, it's not giving output, and I'm thinking of putting "remainder(x-y, y)" in the statement, but still not working.
def remainder(x, y):
if x == y:
return 0
elif x>y:
x = x-y
if x<y:
return x
x=int(input("x: "))
y=int(input("y: "))
print (f'Remainder: {remainder(x, y)}')
'Recursion', by definition, means that your function calls itself at some point. So far, yours doesn't. Consider the flow through your function for a set of inputs - say, x=22 and y=7, and walk through each statement to see what it's doing. This usually helps to debug.
When designing a recursive function, it's usually easiest to start with what you're doing to recur (in this case, subtracting y from x). Then, ask what would be the base case - what are the circumstances that make it impossible to recur further? In this case, if subtracting y from x would put the result below zero. In other words, if y is greater than x. Then, the rest of the function is just setting up for calling itself, and calling itself.
In this case, what you'd actually want to do to implement modulo via recursion is more simple:
def remainder(x, y):
# base case
if y > x:
return x
# recursive case
return remainder(x-y, y)
Each iteration of the function subtracts another y from x, until y is larger than x, at which point whatever x is is returned as the remainder.
Note that this will not work for negative numbers, for what should be obvious reasons.
you can also use this answer you need no recursion.
def remainder(x,y):
ans = x/y
rem = y * (ans-int(ans))
return round(rem)
remainder(132,7)
will give you
6
You need to call the function to perform recursion
def remainder(x, y):
if y==0: # check to avoid infinite loops
return float("Nan")
if x>=y:
return remainder(x-y, y)
else: # base case
return x

Syntax for Greatest Common Divisor - Python

The program below was more precise and shorter than mine, and thus more appealing. I understand mod (%), but the rest of the syntax on the line noted is confusing me. Does anyone know what this syntax is called or how it works?
The problem asked to create a function to find the greatest common divisor (gcd) for two integers, which is the largest number that divides both numbers without a remainder.
For example, the gcd of 20 and 12 is 4.
def gcd(x, y):
while y != 0:
(x, y) = (y, x % y) ## What is happening here? What's this syntax called?
return x
Link to where I found this program: How to calculate a mod b in python?
Thank you so much for your help!
You have stumbled upon tuple assignments!
In a nutshell, in python, You can assign groups of variables so long as you are assigning them from a structure with the same format
Here is a simpler illustration of what is happening:
a,b = 3,5
#a is now equal to 3 and b is now equal to 5
#You literally could go:
# a = 3
# b = 5
#And it would be logically equivalent
a+b
Returns
>>>8
In your function, you are assigning the value of y (the second parameter of the function) to the variable x, and updating the value of y to the remainder of x/y.
I hope this helps.

Sum with index as derivative order

I want to define a sum that contains derivatives of a function, where the summation index is the derivative order.
Simple example:
x, i = symbols("x i")
f = Function("f")(x)
Sum(diff(f,x,i), [i,1,3])
However, this only returns a sum of zeros. I assume this is because it tries to differentiate f wrt x first, and then wrt i. Since f is not a function of i, it evaluates to zero before it is processed by the Sum function. What I want to happen is
diff(f,x,1)
diff(f,x,2)
diff(f,x,3)
etc.
Is there a way to make this work?
sympy.diff(f,x,i) is equivalent to i'th order derivative of f only if i is an integer. In your case it is a symbol.
Use instead the builtin sum() along with a generator expression:
>>> sum(diff(f,x,j) for j in range(1,4))
Derivative(f(x), x) + Derivative(f(x), x, x) + Derivative(f(x), x, x, x)

Sum of squares using lambda functions

I am thinking of different ways to take the sum of squares in python. I have found that the following works using list comprehensions:
def sum_of_squares(n):
return sum(x ** 2 for x in range(1, n))
But, when using lambda functions, the following does not compute:
def sum_of_squares_lambda(n):
return reduce(lambda x, y: x**2 + y**2, range(1, n))
Why is this?
Think about what reduce does. It takes the output of one call and uses it as the first argument when calling the same function again. So imagine n is 4. Suppose you call your lambda f. Then you are doing f(f(1, 2), 3). That is equivalent to:
(1**2 + 2**2)**2 + 3**2
Because the first argument to your lambda is squared, your first sum of squares will be squared again on the next call, and then that sum will be squared again on the next, and so on.
You're only supposed to square each successive element. x**2 + y**2 squares the running total (x) as well as each successive element (y). Change that to x + y**2 and you'll get the correct result. Note that, as mentioned in comments, this requires a proper initial value as well, so you should pass 0 as the optional third argument.
>>> 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
Suppose you plug in 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 squares the "previous" sum as well in the lambda.
(You also have an off by one issue, it should be n+1 in your range calls.)
(for python 3 users)
from functools import reduce
To be able to use reduce.
Second, your function sum_of_squares_lambda won't work the way you expect it to because reduce will take twice (instead of once) every argument except the first and the last one.

Categories