I want to use recursion here but my code is wrong. Help me where I'm wrong. It is only return True. I have to return recursive statement as well as the condition in which the function return False. Basically, I want to expand my code.
def mypalindrome(l):
if l==[] or len(l) == 1:
return(True)
else:
return(mypalindrome(l[1:-1]))
You seem to have most of it right. You just need to call the arguments properly and fix the return value. Additionally, you are missing the check that checks the first and the last character, here's an example:
string = "reallear"
def mypalindrome(string):
if len(string) <= 1:
return True
elif string[0] == string[-1]:
return mypalindrome(string[1:-1])
else:
return False
print mypalindrome(string)
Few ways to check word palindrome
def mypalindrome(l):
if len(l) < 2:
return True
if l[0] != l[-1]:
return False
return mypalindrome(l[1:-1])
or more elegant way
def mypalindrome(l):
return l == l[::-1]
def mypalindrome(l):
if l==[] or len(l) == 1:
return(True)
else:
return(mypalindrome(l[1:-1]) and l[0] == l[-1])
Related
I need to write a code that prints out valid or invalid for an input of letters and numbers for a license plate. The conditions are: first two characters must be letters, characters have to be between 2 and 6, and if numbers are used, 0 should not be the first, nor should a number appear before a letter.
I put the code below on Thonny and cannot understand why len(l) == 4 part of the conditional statement for def valid_order() returns None and does not execute the next line of the code whereas others work fine. My code should return "Valid" for CSAA50, but it returns invalid. Why?
Also, is there an elegant way to write def valid_order()?
def main():
plate = input("Plate: ")
if is_valid(plate):
print("Valid")
else:
print("Invalid")
def is_valid(s):
if s[0:2].isalpha() and 6 >= len(s) >= 2 and s.isalnum() and valid_order(s):
return True
else:
return False
def valid_order(c):
n = []
l = list(c[2:len(c)])
for i in c:
if i.isdigit():
n += i
if n and n[0] == "0":
return False
if len(l) == 2:
if l[0].isdigit() and l[1].isalpha():
return False
if len(l) == 3:
if l[0].isdigit():
if l[1].isalpha() or l[2].isalpha():
return False
else:
if l[1].isdigit() and l[2].isalpha():
return False
if len(l) == 4:
if l[0].isdigit():
if l[1].isalpha() or l[2].isalpha() or l[3].isalpha():
return False
else:
if l[1].isdigit():
if l[2].isalpha() or l[3].isalpha():
return False
else:
if l[2].isdigit() and l[3].isalpha():
return False
else:
return True
main()
I have an exercice where I need to find the index of the first occurence of a number in list. But I also need to return None if index can't be found, meaning the number is not in list.
I need to do that with a recursive function in Python.
I already created a code that does: "find the index of the first occurence of a number in list". And it works.
def index(lst, number_find):
if lst == []:
return None
elif lst[0] == number_find:
return 0
else:
return 1 + index(lst[1:], number_find)
liste = range(51)
print(index(liste, 42))
But I can't write the code that manages the case if the number is not in list.
I have done that:
def index(lst, number_find):
if number_find not in lst:
return None
elif lst == []:
return None
elif lst[0] == number_find:
return 0
else:
return 1 + index(lst[1:], number_find)
liste = range(51)
print(index(liste, 42))
But the use of "not in" is not good here for me because that seems to use some iterative code that I can't use.
You have to protect against the case where None comes back from the recursive call, because 1 + None will raise a TypeError:
def index(lst, number_find):
if lst == []:
return None
elif lst[0] == number_find:
return 0
else:
i = index(lst[1:], number_find)
if i is not None:
return 1 + i
return None # not strictly necessary as None returned implicity
Of course, when you return from every if-block, you can omit any else. Also, None is the default return value, so you can shorten your logic
def index(lst, number_find):
if lst:
if lst[0] == number_find:
return 0
if (i := index(lst[1:], number_find)) is not None:
return 1 + i
Btw, since slicing is O(N) here, all these approaches are quadratic. So here is a solution that has linear complexity:
def index(lst, number_find):
def rec(it, i=0):
if (n := next(it, None)) is not None:
return i if n == number_find else rec(it, i+1)
return rec(iter(lst))
The accepted answer by user2390182 explains in detail how to handle the possible None value returned by the recursive call.
A different approach is to write the function in a tail-recursive way:
def index(lst, number_find, acc=0):
if lst == []:
return None
elif lst[0] == number_find:
return acc
else:
return index(lst[1:], number_find, acc+1)
Note that python doesn't perform tail-rec optimization; but this approach still avoids the 1+None issue.
I have two programs for searching using binary search in Python
Program 1:
def bin(alist,x):
if len(alist)==0:
return False
else:
mid=len(alist)//2
if (alist[mid]==x):
return True
else:
if alist[mid] < x:
#print(alist[mid+1:],x)
bin(alist[mid+1:],x)
else:
#print(alist[:mid],x)
bin(alist[:mid],x)
print (bin([2,3,5,8,9],8))
print (bin([2,3,5,8,9],7))
Program output:
None
None
Program 2:
def bin(alist,x):
if len(alist)==0:
return False
else:
mid=len(alist)//2
if (alist[mid]==x):
return True
else:
if alist[mid]<x:
return bin(alist[mid+1:],x)
else:
return bin(alist[:mid],x)
print(bin([1,5,7,8,9],10))
print(bin([1,4,5,8,9],8))
Program output:
False
True
Why is it so?
In your program 1, only when the list is empty or the value you are searching for in the middle of the list, it would returns you boolean value, that's because you explicitly say return if len(alist)==0 and return True when it meets if (alist[mid]==x):, you have to do the same for the rest conditions as well
def bin(alist,x):
if len(alist)==0:
return False
else:
mid=len(alist)//2
if (alist[mid]==x):
return True
else:
if alist[mid] < x:
#print(alist[mid+1:],x)
bin(alist[mid+1:],x) # -------> return
else:
#print(alist[:mid],x)
bin(alist[:mid],x) # -------> return
When you invoke your bin() method recursively and expect a boolean value, you have to add return in the above highlighted lines.
Ok, so here is my code:
def is_prime(n):
n = abs(int(n))
if n < 2:
return False
elif n == 2:
return True
elif n%2 == 0:
return False
else:
prime(n)
def prime(n):
for x in range(3, int(n**0.5)+1,2):
if n%x == 0:
return False
else:
return True
print is_prime(6577)
But whenever I run this in my shell it returns 'None', I don't understand why. Any help would be appreciated.
Your final else in is_prime returns nothing. You can even remove the else altogether, but that's just personal preference
def is_prime(n):
# You don't really need to take abs value cause you already do a check for < 2 which includes negative numbers
n = abs(int(n))
if n < 2:
return False
elif n==2:
return True
elif n%2 == 0:
return False
return prime(n)
I have this code that should break once it fulfills a certain condition, ie when the isuniquestring(listofchar) function returns True, but sometimes it doesn't do that and it goes into an infinite loop. I tried printing the condition to check if there's something wrong with the condition, but even when the condition is printed true the function still continues running, I have no idea why.
one of the strings that throws up an infinite loop is 'thisisazoothisisapanda', so when I do getunrepeatedlist('thisisazoothisisapanda'), it goes into an infinite loop.
would be really grateful if someone could help
thanks!
Here's my code:
def getunrepeatedlist(listofchar):
for ch in listofchar:
if isrepeatedcharacter(ch,listofchar):
listofindex = checkrepeatedcharacters(ch,listofchar)
listofchar = stripclosertoends(listofindex,listofchar)
print (listofchar)
print (isuniquestring(listofchar))
if isuniquestring(listofchar):
return listofchar
#print (listofchar)
else:
getunrepeatedlist(listofchar)
return listofchar
just for reference, these are the functions I called
def isrepeatedcharacter(ch,list):
if list.count(ch) == 1 or list.count(ch) == 0:
return False
else:
return True
def checkrepeatedcharacters(ch,list):
listofindex=[]
for indexofchar in range(len(list)):
if list[indexofchar] == ch:
listofindex.append(indexofchar)
return listofindex
def stripclosertoends(listofindices,listofchar):
stringlength = len(listofchar)-1
if listofindices[0] > (stringlength-listofindices[-1]):
newstring = listofchar[:listofindices[-1]]
elif listofindices[0] < (stringlength-listofindices[-1]):
newstring = listofchar[listofindices[0]+1:]
elif listofindices[0] == (stringlength-listofindices[-1]):
beginningcount = 0
endcount = 0
for index in range(listofindices[0]):
if isrepeatedcharacter(listofchar[index],listofchar):
beginningcount += 1
for index in range(listofindices[-1]+1,len(listofchar)):
if isrepeatedcharacter(listofchar[index],listofchar):
endcount += 1
if beginningcount < endcount:
newstring = listofchar[:listofindices[-1]]
else:
#print (listofindices[0])
newstring = listofchar[listofindices[0]+1:]
#print (newstring)
return newstring
def isuniquestring(list):
if len(list) == len(set(list)):
return True
else:
return False
It may be due to the fact that you are changing listofchar in your for loop. Try cloning that variable to a new name and use that variable for manipulations and return the new variable.