I'm writing a Higher Order that takes a lambda expression, a number, then number of times it has to repeat that. This is what I have:
#Square Root
sqrt = lambda x: x ** (1/2)
#Repeat
def repeat(f,x,r):
return [f(i) for r in x]
Here's what it should do:
>>> repeat(sqrt, 2, 0)
2
>>> repeat(sqrt, 2, 1)
1.4142135623730951
>>> repeat(sqrt, 2, 2)
1.189207115002721
Here's the error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "main.py", line 66, in repeat
return [f(i) for r in x]
TypeError: 'int' object is not iterable
This is NOT a repeat because I am asking how to fix MY code, not how to do the problem. Also this is NOT homework, it is simply a project to understand higher order functions better.
Something like this would work if you used a for loop.
#Square Root
sqrt = lambda x: x ** (1/2)
#Repeat
def repeat(f,x,r):
for i in range(r):
x = f(x)
return x
print(repeat(sqrt, 2, 2))
A list comprehension is not the right tool here. You want a single value — a list comprehension always creates a list.
Since this seems like an exercise, in keeping with the style of lambdas and higher order functions, you could recurse with something like:
sqrt = lambda x: x ** (1/2)
rep = lambda f, x, r: f(x) if r < 1 else f(rep(f, x, r - 1))
rep(sqrt, 2, 0)
# 1.4142135623730951
rep(sqrt, 2, 1)
# 1.189207115002721
If r will be large, you may have issues with recursion depth, however.
You could also use functools.reduce
from functools import reduce
sqrt = lambda x: x ** (1/2)
rep = lambda f, x, r: reduce(lambda n, _: f(n), range(r+1), x)
rep(sqrt, 2, 0)
# 1.4142135623730951
rep(sqrt, 2, 1)
# 1.189207115002721
#Square Root
sqrt = lambda x: x ** (1/2)
#Repeat
def repeat(f,x,r):
if r > 0:
return repeat(f,f(x),r-1)
else:
return x
print(repeat(sqrt, 2, 2))
>> 1.189207115002721
a solution using recursion
def repeat(f,x,r):
return [f(i) for r in range(x)]
You are trying to iterate number which is not possible
Related
I am confused by the behavior of the reduce function.
In the first example, I get the expected result: (1-1/2) * (1-1/3) = 1/3
>>> reduce(lambda x, y: (1 - 1.0/x) * (1 - 1.0/y), [2,3])
0.33333333333333337
In the second example, I do not get the expected result: (1-1/2) * (1-1/3) * (1-1/5) = 0.2666666
>>> reduce(lambda x, y: (1 - 1.0/x) * (1 - 1.0/y), [2,3,5])
-1.5999999999999996
Can someone please explain me what I am missing?
What you need is a map and reduce:
>>> from functools import reduce
>>> yourlist = [2, 3]
>>> reduce(lambda x, y: x*y, map(lambda x: (1-1/x), yourlist))
0.33333333333333337
>>> yourlist = [2, 3, 5]
>>> reduce(lambda x, y: x*y, map(lambda x: (1-1/x), yourlist))
0.2666666666666667
Because map converts each item to the (1-1/item) and then the reduce multiplies all of them.
Additional remarks:
Instead of the lambda x, y: x * y you could also use the faster operator.mul, for example:
>>> import operator
>>> yourlist = [2, 3, 5]
>>> reduce(operator.mul, map(lambda x: (1-1/x), yourlist))
0.2666666666666667
Thanks #acushner for pointing this out (in the comments).
What went wrong in your function
In this case it's actually quite easy to see what doesn't work, just use a named function and add some prints:
def myfunc(x, y):
print('x = {}'.format(x))
print('y = {}'.format(y))
res = (1 - 1.0/x) * (1 - 1.0/y)
print('res = {}'.format(res))
return res
reduce(myfunc, [2, 3])
# x = 2
# y = 3
# res = 0.33333333333333337
reduce(myfunc, [2, 3, 5])
# x = 2
# y = 3
# res = 0.33333333333333337
# x = 0.33333333333333337
# y = 5
# res = -1.5999999999999996
So it uses the last result as "next" x value. That's why it worked for the length-2-list case but for more elements it simply doesn't apply the formula you want.
Alternative
Instead of using map and reduce you could also use a simple for-loop. It's much easier to get them right and most of the times they are more readable (and in some cases it's faster than reduce).
prod = 1
for item in yourlist:
prod *= 1 - 1 / item
print(prod)
Yes, instead of 1 line it's now 4 lines long but it's easy to understand what is happening (but there might be some edge cases in which that doesn't behave like reduce, for example for empty inputs).
But I generally prefer simple loops over complicated reduce-operations but as always YMMV. :)
EDIT: I approve map/reduce answer above.
To understand why, read this:
https://docs.python.org/2/library/functions.html#reduce
Reduce recursively calls your function on each element of your list with 2 arguments: an accumulator (value of last call) and current element.
So you get:
(1 - 1.0/( (1 - 1.0/2) * (1 - 1.0/3) )) * (1 - 1.0/5)
With:
reduce(lambda acc, x: (1 - 1.0/acc) * (1 - 1.0/x), [2,3,5])
>>-1.5999999999999996
To add to why you get -1.5999999999999996 as your result and for completeness we can compute it using https://docs.python.org/2/library/functions.html#reduce as our guide:
The first iteration will be (which takes our first 2 iterator values of 2 and 3 as x and y):
(1 - 1.0 / 2) * (1 - 1.0 / 3)
which becomes:
0.5 * 0.6666666666666667
which yields:
0.33333333333333337.
We then use 0.33333333333333337 to move on to our next iteration which takes this result as x and our next iteration number of 5 as y:
Therefore, our second iteration will be:
(1 - 1.0 / 0.33333333333333337) * (1 - 1.0/5)
which becomes:
-1.9999999999999996 * 0.8
which yields:
-1.5999999999999996
In your second example you have 3 inputs. You need:
reduce(lambda x, y: (1 - 1.0/x) * (1 - 1.0/y)* (1 - 1.0/z),...
Does some standard Python module contain a function to compute modular multiplicative inverse of a number, i.e. a number y = invmod(x, p) such that x*y == 1 (mod p)? Google doesn't seem to give any good hints on this.
Of course, one can come up with home-brewed 10-liner of extended Euclidean algorithm, but why reinvent the wheel.
For example, Java's BigInteger has modInverse method. Doesn't Python have something similar?
Python 3.8+
y = pow(x, -1, p)
Python 3.7 and earlier
Maybe someone will find this useful (from wikibooks):
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
If your modulus is prime (you call it p) then you may simply compute:
y = x**(p-2) mod p # Pseudocode
Or in Python proper:
y = pow(x, p-2, p)
Here is someone who has implemented some number theory capabilities in Python: http://www.math.umbc.edu/~campbell/Computers/Python/numbthy.html
Here is an example done at the prompt:
m = 1000000007
x = 1234567
y = pow(x,m-2,m)
y
989145189L
x*y
1221166008548163L
x*y % m
1L
You might also want to look at the gmpy module. It is an interface between Python and the GMP multiple-precision library. gmpy provides an invert function that does exactly what you need:
>>> import gmpy
>>> gmpy.invert(1234567, 1000000007)
mpz(989145189)
Updated answer
As noted by #hyh , the gmpy.invert() returns 0 if the inverse does not exist. That matches the behavior of GMP's mpz_invert() function. gmpy.divm(a, b, m) provides a general solution to a=bx (mod m).
>>> gmpy.divm(1, 1234567, 1000000007)
mpz(989145189)
>>> gmpy.divm(1, 0, 5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: not invertible
>>> gmpy.divm(1, 4, 8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: not invertible
>>> gmpy.divm(1, 4, 9)
mpz(7)
divm() will return a solution when gcd(b,m) == 1 and raises an exception when the multiplicative inverse does not exist.
Disclaimer: I'm the current maintainer of the gmpy library.
Updated answer 2
gmpy2 now properly raises an exception when the inverse does not exists:
>>> import gmpy2
>>> gmpy2.invert(0,5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: invert() no inverse exists
As of 3.8 pythons pow() function can take a modulus and a negative integer. See here. Their case for how to use it is
>>> pow(38, -1, 97)
23
>>> 23 * 38 % 97 == 1
True
Here is a one-liner for CodeFights; it is one of the shortest solutions:
MMI = lambda A, n,s=1,t=0,N=0: (n < 2 and t%N or MMI(n, A%n, t, s-A//n*t, N or n),-1)[n<1]
It will return -1 if A has no multiplicative inverse in n.
Usage:
MMI(23, 99) # returns 56
MMI(18, 24) # return -1
The solution uses the Extended Euclidean Algorithm.
Sympy, a python module for symbolic mathematics, has a built-in modular inverse function if you don't want to implement your own (or if you're using Sympy already):
from sympy import mod_inverse
mod_inverse(11, 35) # returns 16
mod_inverse(15, 35) # raises ValueError: 'inverse of 15 (mod 35) does not exist'
This doesn't seem to be documented on the Sympy website, but here's the docstring: Sympy mod_inverse docstring on Github
Here is a concise 1-liner that does it, without using any external libraries.
# Given 0<a<b, returns the unique c such that 0<c<b and a*c == gcd(a,b) (mod b).
# In particular, if a,b are relatively prime, returns the inverse of a modulo b.
def invmod(a,b): return 0 if a==0 else 1 if b%a==0 else b - invmod(b%a,a)*b//a
Note that this is really just egcd, streamlined to return only the single coefficient of interest.
I try different solutions from this thread and in the end I use this one:
def egcd(a, b):
lastremainder, remainder = abs(a), abs(b)
x, lastx, y, lasty = 0, 1, 1, 0
while remainder:
lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder)
x, lastx = lastx - quotient*x, x
y, lasty = lasty - quotient*y, y
return lastremainder, lastx * (-1 if a < 0 else 1), lasty * (-1 if b < 0 else 1)
def modinv(a, m):
g, x, y = self.egcd(a, m)
if g != 1:
raise ValueError('modinv for {} does not exist'.format(a))
return x % m
Modular_inverse in Python
Here is my code, it might be sloppy but it seems to work for me anyway.
# a is the number you want the inverse for
# b is the modulus
def mod_inverse(a, b):
r = -1
B = b
A = a
eq_set = []
full_set = []
mod_set = []
#euclid's algorithm
while r!=1 and r!=0:
r = b%a
q = b//a
eq_set = [r, b, a, q*-1]
b = a
a = r
full_set.append(eq_set)
for i in range(0, 4):
mod_set.append(full_set[-1][i])
mod_set.insert(2, 1)
counter = 0
#extended euclid's algorithm
for i in range(1, len(full_set)):
if counter%2 == 0:
mod_set[2] = full_set[-1*(i+1)][3]*mod_set[4]+mod_set[2]
mod_set[3] = full_set[-1*(i+1)][1]
elif counter%2 != 0:
mod_set[4] = full_set[-1*(i+1)][3]*mod_set[2]+mod_set[4]
mod_set[1] = full_set[-1*(i+1)][1]
counter += 1
if mod_set[3] == B:
return mod_set[2]%B
return mod_set[4]%B
The code above will not run in python3 and is less efficient compared to the GCD variants. However, this code is very transparent. It triggered me to create a more compact version:
def imod(a, n):
c = 1
while (c % a > 0):
c += n
return c // a
from the cpython implementation source code:
def invmod(a, n):
b, c = 1, 0
while n:
q, r = divmod(a, n)
a, b, c, n = n, c, b - q*c, r
# at this point a is the gcd of the original inputs
if a == 1:
return b
raise ValueError("Not invertible")
according to the comment above this code, it can return small negative values, so you could potentially check if negative and add n when negative before returning b.
To figure out the modular multiplicative inverse I recommend using the Extended Euclidean Algorithm like this:
def multiplicative_inverse(a, b):
origA = a
X = 0
prevX = 1
Y = 1
prevY = 0
while b != 0:
temp = b
quotient = a/b
b = a%b
a = temp
temp = X
a = prevX - quotient * X
prevX = temp
temp = Y
Y = prevY - quotient * Y
prevY = temp
return origA + prevY
Well, here's a function in C which you can easily convert to python. In the below c function extended euclidian algorithm is used to calculate inverse mod.
int imod(int a,int n){
int c,i=1;
while(1){
c = n * i + 1;
if(c%a==0){
c = c/a;
break;
}
i++;
}
return c;}
Translates to Python Function
def imod(a,n):
i=1
while True:
c = n * i + 1;
if(c%a==0):
c = c/a
break;
i = i+1
return c
Reference to the above C function is taken from the following link C program to find Modular Multiplicative Inverse of two Relatively Prime Numbers
How can we use pow with a negative exponent in a modular context?
pow(x, y, [z])
If z is present, x and y must be of integer types, and y must be non-negative.
>>> pow(11444, -357)
0.0
>>> pow(11444, -357) % 48731
0.0
>>> pow(11444, -357, 48731)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pow() 2nd argument cannot be negative when 3rd argument specified
In my use case, I want to encrypt a message using a Schnorr scheme:
y = (g ** -w) mod p
but pow won't accept a negative number as the second argument here. As an example, from
g = 11444
p = 48731
w = 357
y should be 7355.
pow won't automatically compute a modular multiplicative inverse for you. Instead, we can compute it ourselves (say via the extended Eulidean algorithm) and then rewrite pow(a,-b,c) as pow((a^-1) mod c, b, c). Stealing the MMI code from this question:
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
we get
>>> g = 11444
>>> p = 48731
>>> w = 357
>>> modinv(g, p)
29420
>>> pow(modinv(g, p), w, p)
7355
As of python 3.8 you can do this. 3.9 adds keyword arguments. Check out there code here. There usage is
>>> pow(38, -1, mod=97)
23
>>> 23 * 38 % 97 == 1
True
def horner(x,coeffs):
result = 0
deriv = 0
for a in coeffs:
result = x*result+a
deriv = x*deriv+result
return result,deriv
this is what I have got. But the value of deriv is not correct which I dont know why..
Your code is right, just need to switch the result and deriv lines round because in your first deriv value you want to be using your result = 0 to get the correct answer :)
I use this function to differenciate:
def differenciate(coefficients):
return [c * (len(coefficients) - i) for i, c in enumerate(coefficients[:-1])]
and this function to evaluate a polinomial:
def call(coefficients, x):
return sum(x ** (len(coefficients) - i - 1) * c for i, c in enumerate(coefficients))
There might be no need to do both in one function. You can do
call(differenciate([1, 2, 3, 4]), 4)
Used here
A regular function can contain a call to itself in its definition, no problem. I can't figure out how to do it with a lambda function though for the simple reason that the lambda function has no name to refer back to. Is there a way to do it? How?
The only way I can think of to do this amounts to giving the function a name:
fact = lambda x: 1 if x == 0 else x * fact(x-1)
or alternately, for earlier versions of python:
fact = lambda x: x == 0 and 1 or x * fact(x-1)
Update: using the ideas from the other answers, I was able to wedge the factorial function into a single unnamed lambda:
>>> map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), range(10))
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
So it's possible, but not really recommended!
without reduce, map, named lambdas or python internals:
(lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10)
Contrary to what sth said, you CAN directly do this.
(lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))(n)
The first part is the fixed-point combinator Y that facilitates recursion in lambda calculus
Y = (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))
the second part is the factorial function fact defined recursively
fact = (lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))
Y is applied to fact to form another lambda expression
F = Y(fact)
which is applied to the third part, n, which evaulates to the nth factorial
>>> n = 5
>>> F(n)
120
or equivalently
>>> (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))(5)
120
If however you prefer fibs to facts you can do that too using the same combinator
>>> (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: f(i - 1) + f(i - 2) if i > 1 else 1))(5)
8
You can't directly do it, because it has no name. But with a helper function like the Y-combinator Lemmy pointed to, you can create recursion by passing the function as a parameter to itself (as strange as that sounds):
# helper function
def recursive(f, *p, **kw):
return f(f, *p, **kw)
def fib(n):
# The rec parameter will be the lambda function itself
return recursive((lambda rec, n: rec(rec, n-1) + rec(rec, n-2) if n>1 else 1), n)
# using map since we already started to do black functional programming magic
print map(fib, range(10))
This prints the first ten Fibonacci numbers: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55],
Yes. I have two ways to do it, and one was already covered. This is my preferred way.
(lambda v: (lambda n: n * __import__('types').FunctionType(
__import__('inspect').stack()[0][0].f_code,
dict(__import__=__import__, dict=dict)
)(n - 1) if n > 1 else 1)(v))(5)
This answer is pretty basic. It is a little simpler than Hugo Walter's answer:
>>> (lambda f: f(f))(lambda f, i=0: (i < 10)and f(f, i + 1)or i)
10
>>>
Hugo Walter's answer:
(lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10)
We can now use new python syntax to make it way shorter and easier to read:
Fibonacci:
>>> (f:=lambda x: 1 if x <= 1 else f(x - 1) + f(x - 2))(5)
8
Factorial:
>>> (f:=lambda x: 1 if x == 0 else x*f(x - 1))(5)
120
We use := to name the lambda: use the name directly in the lambda itself and call it right away as an anonymous function.
(see https://www.python.org/dev/peps/pep-0572)
def recursive(def_fun):
def wrapper(*p, **kw):
fi = lambda *p, **kw: def_fun(fi, *p, **kw)
return def_fun(fi, *p, **kw)
return wrapper
factorial = recursive(lambda f, n: 1 if n < 2 else n * f(n - 1))
print(factorial(10))
fibonaci = recursive(lambda f, n: f(n - 1) + f(n - 2) if n > 1 else 1)
print(fibonaci(10))
Hope it would be helpful to someone.
By the way, instead of slow calculation of Fibonacci:
f = lambda x: 1 if x in (1,2) else f(x-1)+f(x-2)
I suggest fast calculation of Fibonacci:
fib = lambda n, pp=1, pn=1, c=1: pp if c > n else fib(n, pn, pn+pp, c+1)
It works really fast.
Also here is factorial calculation:
fact = lambda n, p=1, c=1: p if c > n else fact(n, p*c, c+1)
Well, not exactly pure lambda recursion, but it's applicable in places, where you can only use lambdas, e.g. reduce, map and list comprehensions, or other lambdas. The trick is to benefit from list comprehension and Python's name scope. The following example traverses the dictionary by the given chain of keys.
>>> data = {'John': {'age': 33}, 'Kate': {'age': 32}}
>>> [fn(data, ['John', 'age']) for fn in [lambda d, keys: None if d is None or type(d) is not dict or len(keys) < 1 or keys[0] not in d else (d[keys[0]] if len(keys) == 1 else fn(d[keys[0]], keys[1:]))]][0]
33
The lambda reuses its name defined in the list comprehension expression (fn). The example is rather complicated, but it shows the concept.
Short answer
Z = lambda f : (lambda x : f(lambda v : x(x)(v)))(lambda x : f(lambda v : x(x)(v)))
fact = Z(lambda f : lambda n : 1 if n == 0 else n * f(n - 1))
print(fact(5))
Edited: 04/24/2022
Explanation
For this we can use Fixed-point combinators, specifically Z combinator, because it will work in strict languages, also called eager languages:
const Z = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v)))
Define fact function and modify it:
1. const fact n = n === 0 ? 1 : n * fact(n - 1)
2. const fact = n => n === 0 ? 1 : n * fact(n - 1)
3. const _fact = (fact => n => n === 0 ? 1 : n * fact(n - 1))
Notice that:
fact === Z(_fact)
And use it:
const Z = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v)));
const _fact = f => n => n === 0 ? 1 : n * f(n - 1);
const fact = Z(_fact);
console.log(fact(5)); //120
See also:
Fixed-point combinators in JavaScript: Memoizing recursive functions
I got some homework about it and figured out something, heres an example of a lambda function with recursive calls:
sucesor = lambda n,f,x: (f)(x) if n == 0 else sucesor(n-1,f,(f)(x))
I know this is an old thread, but it ranks high on some google search results :). With the arrival of python 3.8 you can use the walrus operator to implement a Y-combinator with less syntax!
fib = (lambda f: (rec := lambda args: f(rec, args)))\
(lambda f, n: n if n <= 1 else f(n-2) + f(n-1))
As simple as:
fac = lambda n: 1 if n <= 1 else n*fac(n-1)
Lambda can easily replace recursive functions in Python:
For example, this basic compound_interest:
def interest(amount, rate, period):
if period == 0:
return amount
else:
return interest(amount * rate, rate, period - 1)
can be replaced by:
lambda_interest = lambda a,r,p: a if p == 0 else lambda_interest(a * r, r, p - 1)
or for more visibility :
lambda_interest = lambda amount, rate, period: \
amount if period == 0 else \
lambda_interest(amount * rate, rate, period - 1)
USAGE:
print(interest(10000, 1.1, 3))
print(lambda_interest(10000, 1.1, 3))
Output:
13310.0
13310.0
If you were truly masochistic, you might be able to do it using C extensions, but this exceeds the capability of a lambda (unnamed, anonymous) functon.
No. (for most values of no).