How do I turn a while loop into a recursive method? - python

I need help turning this while loop into a recursive method? How do I do this?
while z <= len(list):
if z = len(list): #base case
return something
else:
#do something else
z += 1

def func(my_list, z):
if z == len(my_list):
return something
else:
# do something else
return func(my_list, z+1)
z = someValue
print func(my_list, z)
You should not use list as variable name.

z = 1
while z <=5:
if z == 5:
print 'base case'
else:
print 'repeated text'
z += 1
This is translated to recursive code as follows. You can work on your case based on this
def recursion(z):
assert z <= 5
if z == 5:
print 'base case'
else:
print 'repeated text'
recursion(z+1)
recursion(1)

I will implement the recursive function using while loop ---Factorial----
(1)It will call the fact function recursively based on while condition
(2)You can add if or nested if according to your problem statement
def fact(num):
while num>1:
return num*fact(num-1)
else:
return num
result = fact(3)
print(result)
6

condition = lambda n: n >= 3
repetition = lambda n: print(f'{n}: Repeating Line')
termination = lambda n: print(f'{n}: Terminal Line')
def recursive(n):
if condition(n):
repetition(n)
n = recursive(n-1)
else:
termination(n)
return n
def iterative(n):
while condition(n):
repetition(n)
n -= 1
termination(n)
return n
def main():
n = 4
print("Recursion Example")
result = recursive(n)
print(f'result = {result}')
print()
print("Iteration Example")
result = iterative(n)
print(f'result = {result}')
print()
main()
>>> Recursion Example
>>> 4: Repeating Line
>>> 3: Repeating Line
>>> 2: Terminal Line
>>> result = 2
>>>
>>> Iteration Example
>>> 4: Repeating Line
>>> 3: Repeating Line
>>> 2: Terminal Line
>>> result = 2

Related

Decimal to binary function in Python using recursion

I am new in Python and trying to write a binary-to-decimal converted function like below
def decimaltobinary(n):
if n > 1:
decimaltobinary(n//2)
print(n%2,end='')
#return n%2
decimaltobinary(4)
This works perfectly fine. Now the question is when I am modifying it as below, it doesn't give me correct result -
def decimaltobinary(n):
if n > 1:
decimaltobinary(n//2)
#print(n%2,end='')
return n%2
a=decimaltobinary(4)
print(a)
Am I missing something with the return statement? Any pointer will be very helpful.
You need to be careful with your return statements. Try this:
def decimaltobinary(n):
def _dtb(n, lst):
if n <= 0:
return lst
lst.append(n&1)
return _dtb(n>>1, lst)
return ''.join(map(str, reversed(_dtb(n, list()))))
print(decimaltobinary(19))
Output:
10011
In the second example returned value from decimaltobinary in if is completely ignored.
What you need to do is assign the returned value to a variable and then return it together with n%2.
Try this:
def decimaltobinary(n):
x = ''
if n > 1:
x = decimaltobinary(n//2)
#print(n%2,end='')
return str(x) + '' + str(n%2)
a=decimaltobinary(4)
print(a)
In the first example you are printing on each iteration of the recursive method.
On the second example you're smashing the return statement.
You can see here:
def decimaltobinary(n):
if n > 1:
print('Making recursion for (n): ', n)
decimaltobinary(n//2)
print('Return for (n): ', n, ', result: ', n%2)
return n%2
a=decimaltobinary(4)
print(a)
Output:
Making recursion for (n): 4
Making recursion for (n): 2
Return for (n): 1 , result: 1
Return for (n): 2 , result: 0
Return for (n): 4 , result: 0
0

How to reduce a lot of "if" statements

def tribonacci(signature, n):
f = 0
if n == 0:
return []
if n == 1:
return [signature[0]]
if n == 2:
return [signature[0], signature[1]]
while len(signature) != n:
i = signature[0 + f] + signature[1 + f] + signature[2 + f]
signature.append(i)
f += 1
return signature
That's a Tribonacci(same with Fibonacci but with 3 numbers) code from codewars.com , I know that it could be more beautiful and elegant but i want to know how to reduce this particular part:
if n == 0:
return []
if n == 1:
return [signature[0]]
if n == 2:
return [signature[0], signature[1]]
Thanks!
You can see in your if statements, when n==0 return is empty list, for n==1, return one item in a list and also for n==2 return two items in a list.
So for that you can do in a one if statement as below:
if 0 <= n < 3:
return list(signature[:n])
And here is your full code for your problem.
def tribonacci(signature, n):
#your code here
f = 0
if 0 <= n < 3:
return list(signature[:n])
while len(signature) != n:
i = signature[0 + f] + signature[1 + f] + signature[2 + f]
signature.append(i)
f += 1
return signature
The 3 cases 0, 1, 2 can be reduced to one, because all return the signature list until the given n
if n < 3: # if 0 <= n < 3: can be used for satefy
return signature[:n]

In Python, how do I return a value from a function when an `if` statement is executed?

In this function, I want to return a value when the if statement is executed.
Since Python always returns something, it returns None.
def Persistence(number, counter):
numArr = [int(i) for i in str(number)]
result = 1
data = None
for j in numArr:
result *= j
if len(str(number)) == 1:
data = str(f'Done. {counter} steps taken')
print(data)
# return data
else:
counter = counter + 1
Persistence(result, counter)
# return data
print(Persistence(333,0))
Maybe I put the return keyword in the wrong place (I checked by putting it in two different places, marked as a comment) or something else, but I couldn't figure it out.
Please help me out. Also, if there is another way to count the recursion steps besides my technique, please let me know.
Maybe try this :
def Persistence(number, counter):
numArr = [int(i) for i in str(number)]
result = 1
for j in numArr:
result *= j
if len(str(number)) == 1:
return str(f'Done. {counter} steps taken')
counter = counter + 1
return Persistence(result, counter)
print(Persistence(333,0))
Hope it helps
The issue is that you're not setting the value from the else call to persistence to anything. The following code return the data value for me:
def Persistence(number, counter):
numArr = [int(i) for i in str(number)]
result = 1
data = None
for j in numArr:
result *= j
if len(str(number)) == 1:
data = str(f'Done. {counter} steps taken')
print(data)
return data
else:
counter = counter + 1
data = Persistence(result, counter)
return data
x = Persistence(333, 0)
Then if we print x:
print(x)
# Done. 3 steps taken
Your logic to count the recursion steps is basically correct, you just need to place the return statements for both the:
1)Base case
2)The recursive call itself
The following modification to your code will do the trick of what you are asking:
def Persistence(number, counter):
numArr = [int(i) for i in str(number)]
result = 1
data = None
for j in numArr:
result *= j
if len(str(number)) == 1:
data = str(counter)
return data
else:
counter = counter + 1
return Persistence(result, counter)
print(Persistence(333,0))
The above code will return the output of:
3
Please note that the reason you were getting "None" as the output in your original code is because you were not making a return at the actual recursive call itself: **return** Persistence(result, counter)
So when you ran print(Persistence(333,0)) it was returning nothing resulting in the None.
This question is better to learn about recursion than you may think. But we won't muddy the waters by mixing recursion (functional style) with statements and side effects (imperative style).
It looks like you're trying to calculate multiplicative root and persistence. Instead of putting all concerns of the computation into a single function, break it down into sensible parts -
def digits (n = 0):
if n < 10:
return [ n ]
else:
return digits (n // 10) + [ n % 10 ]
def product (n = 0, *more):
if not more:
return n
else:
return n * product (*more)
def mult_root (n = 0):
if n < 10:
return [ n ]
else:
return [ n ] + mult_root (product (*digits (n)))
def mult_persistence (n = 0):
return len (mult_root (n)) - 1
print (mult_persistence (333))
# 3
print (mult_root (333))
# [ 333, 27, 14, 4 ]

How to use a variable to find another variable in a list - python

(Python 3.x)
z=[]
x=0
while 1==1:
x=x+1
y=1
z.append(x)
while y==1:
a = 0
b = 0
if z(a)==x:
print(x)
y = 2
elif x%z(a)!= 0:
a = a+1
elif b == 2:
y = 2
else:
b = b+1
So, I made a code to find all the prime numbers until python crashes. However, it relies on z(a) for it to work. The idea is that as "a" changes, it moves on in the list.
"z(a)" is where the error lies, so does anyone know a way to fix this?
z is a list. You can approach values inside it by indexes using the z[a] operator (and not z(a) which assumes a function call with a as parameter).
I've taken the liberty of using boolean variables, += operators and unpacking values:
z = []
x = 0
while True:
x += 1
y = True
z.append(x)
while y:
a, b = 0, 0
if z[a] == x:
print(x)
y = False
elif x % z[a]: a += 1
elif b == 2: y = False
else: b += 1
I believe that's what you want to achieve (infinitely incrementing prime generator):
def prime (n): return not any([n % i == 0 for i in range(2, n)])
x = 0
while True:
if prime(x): print(x)
x += 1

highest palindrome with 3 digit numbers in python

In problem 4 from http://projecteuler.net/ it says:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 * 99.
Find the largest palindrome made from the product of two 3-digit numbers.
I have this code here
def isPalindrome(num):
return str(num) == str(num)[::-1]
def largest(bot, top):
for x in range(top, bot, -1):
for y in range(top,bot, -1):
if isPalindrome(x*y):
return x*y
print largest(100,999)
It should find the largest palindrome, it spits out 580085 which I believe to be correct, but project euler doesn't think so, do I have something wrong here?
When I revered the for loop I didn't think it through, I removed the thing that checks for the biggest, silly me. Heres the working code
def isPalindrome(num):
return str(num) == str(num)[::-1]
def largest(bot, top):
z = 0
for x in range(top, bot, -1):
for y in range(top,bot, -1):
if isPalindrome(x*y):
if x*y > z:
z = x*y
return z
print largest(100,999)
it spits out 906609
Iterating in reverse doesn't find the largest x*y, it finds the palindrome with the largest x. There's a larger answer than 580085; it has a smaller x but a larger y.
This would more efficiently be written as:
from itertools import product
def is_palindrome(num):
return str(num) == str(num)[::-1]
multiples = ( (a, b) for a, b in product(xrange(100,999), repeat=2) if is_palindrome(a*b) )
print max(multiples, key=lambda (a,b): a*b)
# (913, 993)
You'll find itertools and generators very useful if you're doing Euler in Python.
Not the most efficient answer but I do like that it's compact enough to fit on one line.
print max(i*j for i in xrange(1,1000) for j in xrange(1,1000) if str(i*j) == str(i*j)[::-1])
Tried making it more efficient, while keeping it legible:
def is_palindrome(num):
return str(num) == str(num)[::-1]
def fn(n):
max_palindrome = 1
for x in range(n,1,-1):
for y in range(n,x-1,-1):
if is_palindrome(x*y) and x*y > max_palindrome:
max_palindrome = x*y
elif x * y < max_palindrome:
break
return max_palindrome
print fn(999)
Here I added two 'break' to improve the speed of this program.
def is_palindrome(num):
return str(num) == str(num)[::-1]
def max_palindrome(n):
max_palindrome = 1
for i in range(10**n-1,10**(n-1)-1,-1):
for j in range(10**n-1,i-1,-1):
if is_palindrome(i*j) and i*j > max_palindrome:
max_palindrome = i * j
break
elif i*j < max_palindrome:
break
return max_palindrome
n=int(raw_input())
print max_palindrome(n)
Simple:
def is_pallindrome(n):
s = str(n)
for n in xrange(1, len(s)/2 + 1):
if s[n-1] != s[-n]:
return False
return True
largest = 0
for j in xrange(100, 1000):
for k in xrange(j, 1000):
if is_pallindrome(j*k):
if (j*k) > largest: largest = j*k
print largest
Each time it doesnot have to start from 999 as it is already found earlier.Below is a simple method using string function to find largest palindrome using three digit number
def palindrome(y):
z=str(y)
w=z[::-1]
if (w==z):
return 0
elif (w!=z):
return 1
h=[]
a=999
for i in range (999,0,-1):
for j in range (a,0,-1):
l=palindrome(i*j)
if (l==0):
h=h+[i*j]
a-=1
print h
max=h[0]
for i in range(0,len(h)):
if (h[i] > max):
max= h[i]
print "largest palindrome using multiple of three digit number=%d"%max
Here is my code to solve this problem.
lst = []
for i in range(100,1000):
for n in range(2,i) :
lst.append (i* n)
lst.append(i*i)
lst2=[]
for i in lst:
if str(i) == str(i)[::-1]:
lst2.append(i)
print max(lst2)
Here is my Python code:
max_pal = 0
for i in range(100,999):
for j in range(100,999):
mult = i * j
if str(mult) == str(mult)[::-1]: #Check if the number is palindrome
if mult > max_pal:
max_pal = mult
print (max_pal)
def div(n):
for i in range(999,99,-1):
if n%i == 0:
x = n/i
if x % 1 == 0:
x = n//i
if len(str(x)) == 3:
print(i)
return True
return False
def palindrome():
ans = []
for x in range(100*100,999*999+1):
s = str(x)
s = int (s[::-1])
if x - s == 0:
ans.append(x)
for x in range(len(ans)):
y = ans.pop()
if div(y):
return y
print(palindrome())
580085 = 995 X 583, where 906609 = 993 X 913.
Found it only by applying brute-forcing from top to bottom!
Here is the function I made in python to check if the product of 3 digit number is a palindrome
Function:
def is_palindrome(x):
i = 0
result = True
while i < int(len(str(x))/2):
j = i+1
if str(x)[i] == str(x)[-(j)]:
result = True
else:
result = False
break
i = i + 1
return result
Main:
max_pal = 0
for i in range (100,999):
for j in range (100,999):
x = i * j
if (is_palindrome(x)):
if x > max_pal:
max_pal = x
print(max_pal)
Here is my solution for that:
lst1 = [x for x in range(1000)]
palindrome = []
def reverse(x):
a = str(x)[::-1]
return int(a)
x = 0
while x < len(lst1):
for y in range(1000):
z = lst1[x] * y
if z == reverse(z):
palindrome.append(z)
x += 1
duppal = set(palindrome)
sortpal = sorted(duppal)
total = sortpal[-1]
print(sortpal)
print('Largest palindrome: ' + str(total))
ReThink: efficiency and performance
def palindrome(n):
maxNumberWithNDigits = int('9' * n) #find the max number with n digits
product = maxNumberWithNDigits * maxNumberWithNDigits
#Since we are looking the max, stop on the first match
while True:
if str(product) == str(product)[::-1]: break;
product-=1
return product
start=time.time()
palindrome(3)
end=time.time()-start
palindrome...: 997799, 0.000138998031616 secs

Categories

Resources