Using Reduce Function in Python To Find Factorial - python

Hi I'm trying to write a function to find the factorial product of any given number. For example for factorial (6) I would get the product of 6*5*3*2*1.
so for factorial(3) the output would be 6.
The functions I have so far are:
import functools
def mult(x, y):
return x * y
def factorial(n):
if n == 0:
return 1
else:
functools.reduce(mult(n,factorial(n - 1)))
But I keep getting an error that Python is expecting 2 arguments and 1 is given. I know I have to use range somehow but I can't figure it out. How do I edit my existing code so that it runs properly?

you can do this pretty easily:
>>> import functools, operator
>>> functools.reduce(operator.mul, xrange(1, 6))
120
Note that the first argument is a function (you're passing the result of a function call). the second argument is an iterable. Also note that written this way, no recursion is needed...
operator.mul is equivalent to your mult function

import functools
def factorial(n):
if n == 0:
return 1
else:
return functools.reduce(lambda x,y: x*y, range(1,n+1))
print factorial(3)
Of course you can use you own multi function instead of the lambda if you prefer.

>>> x = 8
>>> reduce(lambda x,y: x*y, [1, 1] if x == 0 else xrange(1, x+1))

n = int(input())
import functools
def factorial(n):
if n == 0:
return 1
else:
return functools.reduce(lambda x,y: x*y , range(1,n+1))
print(factorial(n))
output:-
Input
3
Solution output
6

If you are using 2.7, then I would reccomend looking here at the documentation for reduce. If you are using 3, then we see that
functools.reduce is the same as 2.7's reduce
That is, we see that we need to call functools in the same way as in 2.7. The following is a representation of that:
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
, which translates to:
functools.reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
For the case of your example, you are making your own operator, which is confusing reduce. This can be solved by adding import operator , and then using the methods that are declared that are defined in operator (i.e. operator.add).
I hope this helps clear things up!

from functools import reduce
f=lambda x,y:x*y
def factorial(number):
if(number==1):
return 1
else:
return reduce(f,range(1,number+1))
print(factorial(n))

Here is a perfect snippet for the factorial function using a reduce built-in function. This will print 1 when n=0, as the factorial of 0 is 1.
# Read the input as an integer
n = 4
# Import the reduce() function
from functools import reduce
fact = lambda x,y:x*y
print(1 if n == 0 else reduce(fact,range(1,n+1)))

My solution:
from functools import reduce
list_num = list(range(1,8,1)) # instead of 8 put the number+1 of which you need factorial
def fact_num(acc, item):
return acc*item
print(reduce(fact_num, list_num,1))

from functools import reduce
n = int(input("Enter a number: "))
print("Factorial is:", reduce(lambda x, y: x*y, range(1, n+1)))

n = int (input ("Enter a natural number "))
n_list = range(1,n+1)
from functools import reduce
factorial = reduce(lambda x,y: x*y, n_list) factorial

-----Import the reduce() function
from functools import reduce
---Read the input as an integer
n = int(input())
fact=reduce(lambda x,y:x+y,range(n+1))
print(fact)

Related

How can we can we calculate the factorial of a number using python lambda function without recursion

I wanted to calculate the the factorial of a number using python lambda function without recursion.
I did without lamda function
def factorial_number(num):
fact = 1
while(num>=1):
fact = num* fact;
num = num-1
return fact
factorial_number(5)
I have tried the below code without recursion(using lambda).
factorial_number = lambda num : 1 while(num>=1) fact = fact*num num = num-1 return fact
The above code doesn't work.
Error:
File "<ipython-input-1-62f7b66fbfd2>", line 1
factorial_number = lambda num : 1 while(num>=1) fact = fact*num num = num-1 return fact
^
SyntaxError: invalid syntax
But i want to implement using lamda function, without in-built functions and without recursive method. so that i can learn more how to use lamba funcitons effectively.
please help me with the code.
def factorial(n):
t = 1
for i in range(n, 1, -1):
t *= i
return t
>>> factorial(4)
24
You can use functools.reduce()
from functools import reduce
num = int(input('Enter number: '))
fact = lambda num: reduce(lambda x, y: x * y, range(1, num+1))
print(f'{num}! = {fact(num)}')
You can simply use math.factorial.
import math
fctrl = lambda: math.factorial(x)
or
from math import factorial
fctrl = lambda: factorial(x)

Find minimum non-negative integer, which not satisfies the condition

I have function f that takes int and return bool. I want to find minimum non-negative integer x, for which f(x) is False. How can I do it in most pythonic way (ideally one line)?
Here is how I do it now:
x = 0
while f(x):
x += 1
print(x)
I want something like:
x = <perfect one line expression>
print(x)
Here it is, using next:
from itertools import count
x = next(i for i in count() if not f(i))
Demo:
>>> def f(x):
... return (x - 42)**2
...
>>> next(i for i in count() if not f(i))
42
A similar functional approach with itertools.filterfalse and itertools.count could be
from itertools import filterfalse, count
x = next(filterfalse(f, count()))
Or you can swap out filterfalse with dropwhile, which while performantly similar maintains the same syntax across Python 2 and 3 (thanks to rici).
from itertools import dropwhile, count
x = next(dropwhile(f, count()))
If you'd like a single line without imports, one way might be a list comprehension (Python 2.7 / PyPy):
def f(x):
return True if x == 5 else False
x = [g(0) for g in [lambda x: x if f(x) else g(x+1)]][0]
print(x)

How to repeat a function n times

I'm trying to write a function in python that is like:
def repeated(f, n):
...
where f is a function that takes one argument and n is a positive integer.
For example if I defined square as:
def square(x):
return x * x
and I called
repeated(square, 2)(3)
this would square 3, 2 times.
That should do it:
def repeated(f, n):
def rfun(p):
return reduce(lambda x, _: f(x), xrange(n), p)
return rfun
def square(x):
print "square(%d)" % x
return x * x
print repeated(square, 5)(3)
output:
square(3)
square(9)
square(81)
square(6561)
square(43046721)
1853020188851841
or lambda-less?
def repeated(f, n):
def rfun(p):
acc = p
for _ in xrange(n):
acc = f(acc)
return acc
return rfun
Using reduce and lamba.
Build a tuple starting with your parameter, followed by all functions you want to call:
>>> path = "/a/b/c/d/e/f"
>>> reduce(lambda val,func: func(val), (path,) + (os.path.dirname,) * 3)
"/a/b/c"
Something like this?
def repeat(f, n):
if n==0:
return (lambda x: x)
return (lambda x: f (repeat(f, n-1)(x)))
Use an itertools recipe called repeatfunc that performs this operation.
Given
def square(x):
"""Return the square of a value."""
return x * x
Code
From itertools recipes:
def repeatfunc(func, times=None, *args):
"""Repeat calls to func with specified arguments.
Example: repeatfunc(random.random)
"""
if times is None:
return starmap(func, repeat(args))
return starmap(func, repeat(args, times))
Demo
Optional: You can use a third-party library, more_itertools, that conveniently implements these recipes:
import more_itertools as mit
list(mit.repeatfunc(square, 2, 3))
# [9, 9]
Install via > pip install more_itertools
Using reduce and itertools.repeat (as Marcin suggested):
from itertools import repeat
from functools import reduce # necessary for python3
def repeated(func, n):
def apply(x, f):
return f(x)
def ret(x):
return reduce(apply, repeat(func, n), x)
return ret
You can use it as follows:
>>> repeated(os.path.dirname, 3)('/a/b/c/d/e/f')
'/a/b/c'
>>> repeated(square, 5)(3)
1853020188851841
(after importing os or defining square respectively)
I think you want function composition:
def compose(f, x, n):
if n == 0:
return x
return compose(f, f(x), n - 1)
def square(x):
return pow(x, 2)
y = compose(square, 3, 2)
print y
Here's a recipe using reduce:
def power(f, p, myapply = lambda init, g:g(init)):
ff = (f,)*p # tuple of length p containing only f in each slot
return lambda x:reduce(myapply, ff, x)
def square(x):
return x * x
power(square, 2)(3)
#=> 81
I call this power, because this is literally what the power function does, with composition replacing multiplication.
(f,)*p creates a tuple of length p filled with f in every index. If you wanted to get fancy, you would use a generator to generate such a sequence (see itertools) - but note it would have to be created inside the lambda.
myapply is defined in the parameter list so that it is only created once.

Repeated Function Application

I'm having trouble with a question which follows: Write a recursive function repeatedlyApply that takes as arguments a function
f of one argument and a positive integer n. The result of repeatedlyApply is a function of one argument that applies f to that argument n times.
So, for example, we would have
repeatedlyApply(lambda x: x+1,10)(100) ==> 110
You may assume that the following function has been defined. You don't have to use it, but it can contribute to a pretty solution.
def compose(f,g):
return lambda x: f(g(x))
So far i've written this
def compose(f,g):
return lambda x: f(g(x))
def recApply(f,n):
for i in range(n):
return recApply(compose(f,f), n-1)
return f
I'm going wrong somewhere because using the above example recApply(lambda x: x+1,10)(100) i get 1124.
Help much appreciated
Correct answer is:
def recApply(func, n):
if n > 1:
rec_func = recApply(func, n - 1)
return lambda x: func(rec_func(x))
return func
And the output:
>>>> print recApply(lambda x: x+1,10)(100)
110
Your function needs some work:
You have a return inside your for loop, so you return immediately instead of running the loop.
You have a recursive call inside your for loop, so you are doing a bit too much iteration. Choose one or the other.
Be careful when you stack function compositions on top of each other, you are doing power composition rather than linear composition.
Can you tell us what precisely you are trying to do?
EDIT: Since everybody else is posting an answer:
recApply = lambda f, n: lambda x: x if n == 0 else recApply(f, n-1)(f(x))
I have a solution based on lambdas:
>>> f = lambda x: x + 10
>>> iterate = lambda f, n, x : reduce(lambda x, y: f(x), range(n), x)
>>> iterate(f, 10, 3)
103
>>> iterate(f, 4, 4)
44
>>> f10 = lambda x: iterate(f, 10, x)
>>> f10(5)
105
I assume this is an exercise of some sort. There are a few ways you could do it, here's a short one:
>>> repeatedlyApply = lambda f, n: reduce(lambda f1, f2: compose(f1, f2), [f]*n)
>>> repeatedlyApply(lambda x: x+1,10)(100)
110

Replace the built-in min functions in python

I should write a function min_in_list(munbers), which takes a list of
numbers and returns the smallest one. NOTE: built-in function min is NOT allowed!
def min_in_list(numbers):
the_smallest = [n for n in numbers if n < n+1]
return the_smallest
What's wrong?
def min_of_two(x, y):
if x >= y: return x
else: return y
def min_in_list(numbers):
return reduce(min_of_two, numbers)
You have to produce 1 number from list, not just another list. And this is work for reduce function (of course, you can implement it without reduce, but by analogy with it).
Here you go. This is almost certainly about as simple as you could make it. You don't even have to give me credit when you turn the assignment in.
import itertools
import functools
import operator
def min(seq, keyfun=operator.gt):
lt = lambda n: functools.partial(keyfun, n)
for i in seq:
lti = lt(i)
try:
next(itertools.ifilter(lti, seq))
except:
return i
min = lambda n: return reduce(lambda x,y: (x>y) and return x or return y,n)
Never been tested, use at your own risk.

Categories