It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I need help writing a recursive function which detects whether a string is a palindrome. But i can't use any loops it must be recursive. Can anyone help show me how this is done . Im using Python.
def ispalindrome(word):
if len(word) < 2: return True
if word[0] != word[-1]: return False
return ispalindrome(word[1:-1])
And here is the best one liner
def ispalindrome(word):
return word == word[::-1]
From a general algorithm perspective, the recursive function has 3 cases:
1) 0 items left. Item is a palindrome, by identity.
2) 1 item left. Item is a palindrome, by identity.
3) 2 or more items. Remove first and last item. Compare. If they are the same, call function on what's left of string. If first and last are not the same, item is not a palindrome.
The implementation of the function itself is left as an exercise to the reader :)
If a string is zero or one letters long, it's a palindrome.
If a string has the first and last letters the same, and the remaining letters (I think it's a [1: -1] slice in Python, but my Python is a bit rusty) are a palindrome, it's a palindrome.
Now, write that as a palindrome function that takes a string. It will call itself.
Since we're posting code anyway, and no one-liner has been posted yet, here goes:
def palindrome(s):
return len(s) < 2 or s[0] == s[-1] and palindrome(s[1:-1])
Here's another viewpoint
A palindromic string is
Some letter, x.
Some palindromic substrinng.
The same letter, x, repeated.
Also, note that you may be given a proper English sentence "Able was I ere I saw Elba." with punctuation. Your palindrome checker may have to quietly skip punctuation. Also, you may have to quietly match without considering case. This is slightly more complex.
Some leading punctuation. Some letter, x.
Some palindromic substring.
Some letter, x, repeated without regard to case. Some trailing punctuation.
And, by definition, a zero-length string is a palindrome. Also a single-letter string (after removing punctuation) is a palindrome.
Here's a way you can think of simple recursive functions... flip around the problem and think about it that way. How do you make a palindrome recursively? Here's how I would do it...
def make_palindrome():
maybe:
return ""
elsemaybe:
return some_char()
else:
c = some_char()
return c + make_palindrome() + c
Then you can flip it around to build the test.
The function should expect a string. If there is more then one letter in the string compare the first and the last letter. If 1 or 0 letters, return true. If the two letters are equal call the function then again with the string, without the first and the last letter. If they are not equal return false.
palindrom( word):
IF length of word 1 or 0 THEN
return 0;
IF last and first letter equal THEN
word := remove first and last letter of word;
palindrom( word);
ELSE
return false;
My solution
#To solve this I'm using the stride notation within a slice [::]
def amazonPalindrome(input):
inputB = input
input = input[::-1]
#print input
noPalindrome = inputB + " is not a palindrome"
isPalindrome = inputB + " is a palindrome"
#compare the value of the reversed string to input string
if input[0]!= input[-1]:
print noPalindrome
else:
print isPalindrome
#invoking the def requires at least 1 value or else it fails
#tests include splitting the string,mixing integers, odd amount palindromes.
#call the def
amazonPalindrome('yayay')
a=raw_input("enter the string:")
b=len(a)
c=0
for i in range(b):
if a[i]==a[-(i+1)]:
c=c+1
if c==b:
print a,"is polindrome"
else:
print a,"is not polindrome"
n=raw_input("Enter a number===>")
n=str(n)
l=len(n)
s=""
for i in range(1,l+1):
s=s+n[l-i]
if s==n:
print "Given number is polindrom"
else:
print "Given number is not polindrom"
Related
The task was to write a function with name count_letter that takes a list of words and certain letter and returns amount of words where this letter is found at least once. And, we have to use a for loop.
So I did a list of some programming languages and letter "a", and tried to apply everything we learned so far plus some internet tutorials to understand how to translate human logic into lines of code, but obviously I am missing something, because it doesn't work :(
That is how my code looks like at the moment:
mylist = ['fortran', 'basic', 'java', 'python', 'c++']
letter = 'a'
a_list = []
def count_letter(mylist):
count = 0
for i in range(len(mylist)):
if letter in i:
count += 1
a_list.append(i)
return a_list
print(len(a_list))
Result is - no result. Online-python compiler returns response ** process exited - return code: 0 **
My question is - what could I miss or positioned wrongly that loop doesn't work. I want to understand it for myself.
In tutorials I have found one construction which returns correct answer (and looks very elegant and compact), but it has no function, so it is not really what we needed to write:
mylist = ['fortran', 'basic', 'java', 'python', 'c++']
letter = 'a'
res = len ([ele for ele in mylist if letter in ele])
print ('Amount of words containing a: ' +str(res))
Here system response: 3 , as expected.
Please tell me what should I check in code #1.
Few mistakes I found in your code:
When you do for i in range(len(mylist)), you are actually looping through the numbers 1,2,... instead of elements of mylist. So you have to use "for i in mylist" to loop through elements of the array mylist.
When you return from a function, the code that is after the return is not executed. So you have to print it first and then return from the function.
Don't forget to call the function. Otherwise the function won't be executed.
No need count variable as you can access the length using len method.
mylist = ['fortran', 'basic', 'java', 'python', 'c++']
letter = 'a'
a_list = []
def count_letter(mylist):
for i in mylist:
if letter in i:
a_list.append(i)
print(len(a_list))
return a_list
print(count_letter(mylist))
All the best in your journey!
Personally, I find Python source code easier to read when things are indented by four spaces. So, here is your function again with a wider indentation:
def count_letter(mylist):
count = 0
for i in range(len(mylist)):
if letter in i:
count += 1
a_list.append(i)
return a_list
print(len(a_list))
for i in range(...) will iterate over a collection of integers. So, i will take on a new integer value for each iteration of the loop. First i will be 0, then 1 on the next iteration, and so on.
You then ask if letter in i:. This can never be true. letter is a string, and i is an integer. A string can never be "in" an integer - so this if-statement will never execute. Rather, you want to check if letter is in the current word (the ith word in the list). The if-statement should read:
if letter in mylist[i]:
...
Where mylist[i] is the current word.
You then increment count and append i to a_list. You probably meant to append mylist[i] to a_list, but I don't see why you even need a_list. You just need count, since that keeps track of how many words you've encountered so far for which the condition is true. count is also the variable you should be returning in the end, since that is the purpose of the function: to return the number of words (not the words themselves) which contain a certain letter.
Also, the way your final print statement is indented makes it part of the function's body. It's after the return, though, which means it will never actually get a chance to print. When you use return inside a function, it ends the function, and flow of execution returns to the place from which the function was originally invoked.
One final change that needs to be applied, is that your function should accept a letter to look for as a parameter. Right now, your function only takes one parameter - the list of words through which to search.
Here are the changes I would apply to your code:
def count_letter(words, letter): # I find 'words' is a better name than 'mylist'.
count = 0
for i in range(len(words)):
current_word = words[i]
if letter in current_word:
count += 1
return count
Here is how you might use the function:
words = ["hello", "world", "apple", "sauce"]
letter = "e"
count = count_letter(words, letter)
print("The letter '{}' appeared in {} words.".format(letter, count))
Output:
The letter 'e' appeared in 3 words.
I think that 'takes' means that function must be defined with two parameters: words_list and letter:
def count_letter(words_list, letter):
Algorithm in natural language could be: give me sum of words where letter is present for every word in words list.
In Python it can be expressed as:
def count_letter(words_list, letter):
return sum(letter in word for word in words_list)
Some explanation: letter in word returns boolean value (True or False) and in Python bools are subclass of integer (True is 1 and False is 0). If letter is in word the result would be 1 and if not it would be 0. Summing up of results gives number of words where letter is present
I have read all your answers, some important points I wrote down, sat today again with my code, and after some more tries it worked...
So final version looks like:
words = ['fortran', 'basic', 'java', 'python', 'c++']
letter = "a"
def count_letter(words, letter):
count = 0
for word in words:
if letter in word:
count += 1
return count
print(count_letter((words),letter))
System response:
3
What is not yet obvious for me: correct indents (they were also part of a problem), and additional pair of parentheses around words in print line. But it comes with learning.
Thank you once again!
def isPal(s):
if len(s) <= 1:
print(s)
else:
print(s)
s[0] == s[-1] and isPal((s[1:-1]))
print(s)
print("HI")
x = isPal("deleveled")
print(x)
Output:
deleveled
elevele
level
eve
v
HI
eve
HI
level
HI
elevele
HI
deleveled
HI
None
Let's break down the program.
Firstly, if the string given to isPal() is one or zero characters, it's printed. In other words, once we can't simplify any more, we stop simplifying and just output what we have.
Otherwise (when we have two or more characters), we check that the first and last character are equal, and then perform the same algorithm on the string without these two characters. This continues until we have one or zero characters, as described above.
The reason the word is rebuilding at the end is that you have printed the string again after your recursive function call. So after going 'deeper' into your word, you print where you came from too.
EDIT: The reason 'HI' is printed is that after you've done your going 'deeper' into the word and have come back out, you print 'HI' each time. So every time you take one step back out of the program (one more letter back at the start and end), you print 'HI'.
I think the issue with your code is that you've not actually told the function to answer the 'isPal' question with a True or False.
def isPal(s):
if len(s) <= 1:
print(s)
return True
else:
print(s)
return (s[0] == s[-1] and isPal((s[1:-1])))
x = isPal("deleveled")
print(x)
This code will now return True or False depending on whether your algorithm detects that the string is a palindrome or not.
Your code actually did what you wanted it to, you just hadn't returned the result of your check.
I am trying to determine if a given word is a palindrome.
The goal of my code is that the function will take a word, and remove it of any punctuation or spaces. If the length of the word is 0 or 1, it is returned that the word is a palindrome. I then check if the first and last letter are the same. If they aren't, it is returned that it is not a palindrome. If they first and last letters the same, I then want to replace those two letters with spaces and call my function again. The reason I replace the letters with spaces is so that it will be edited by my initial edit statements.
def palindrome(word):
editWord = word.strip(" ").strip("!").strip("?")
stringOne = "A palindrome"
stringTwo = "Not a palindrome"
if len(editWord) == 0 or len(editWord) == 1:
return stringOne
elif editWord[0] != editWord[-1]:
return stringTwo
else:
word = editWord.replace(editWord[0], " ").replace(editWord[-1], " ")
palindrome(word)
return stringOne
print(palindrome("area"))
When tested with single letters it functions properly, as well if I test words like 'are' which obviously is not a palindrome. However, if I call the word area it returns "A palindrome" when it is not. This makes it seem like it is not calling my function again. Any suggestions on why this is happening?
For recursion to work properly here, your else statement should say something along the lines of "the word is a palindrome if the outer characters are equal and the remainder is also a palindrome". Instead, your code is replacing all occurrences of the outer characters with spaces, checking if the word is a palindrome, and ignoring the result to always return "yes".
You can do a proper recursion using slicing instead of replacement:
else:
return palindrome(editWord[1:-1])
Another alternative to replacing the letters while still doing this recursively to to keep track of the index in the word and increment it on recursion. This saves you from having to make new slices on each recursion. In this case your edge case will be when the index is in the middle of the word.
def palindrome(word, i = 0):
if i >= len(word)//2:
return True
if word[i] != word[-(i+1)]:
return False
return palindrome(word, i+1)
palindrome("mrowlatemymetalworm") # true
I am currently taking a course on Python and am currently struggling with one portion of my homework.
The question is asking us to construct a function that checks a string to see if it is a palindrome. The problem I am having is that for one of the tests my instructor has provided is for the palindrome "Never odd or even" which contains spaces. The spaces are causing my function to fail because it won't just use the letters in the phrase.
My current code is:
def is_palindrome(phrase):
return phrase == phrase[::-1]
She is testing with the code:
assert is_palindrome("Never odd or even")
Any help would be appreciated! Thanks.
I think this is what you want:-
is_palindrome("Never odd or even".replace(" ", "").lower())
Or
If you want to change your function then your function look like:
def is_palindrome(phrase):
phrase=phrase.replace(" ","").lower()
return phrase == phrase[::-1]
and you can call it using is_palindrome("Never odd or even")
First remove the spaces, then use recursion, checking only if the first and last characters are the same, recursing on the inner part.
def is_palindrome(x):
x = "".join(x.split()).lower()
if (len(x) <= 1): return True
if x[0] != x[-1]: return False
return is_palindrome(x[1:-1])
This question already has answers here:
Python reverse() for palindromes
(7 answers)
Closed 9 years ago.
I have a final coming up, and the teacher has said that he plans to include a palindrome checker on the list of problems. Basically, I need to write two separate functions, one to test if a list is a palindrome (if it is, return True), and the other to test a string.
Here is what I have so far. It seems to be giving me trouble:
def palindrome(s)
index = 0
index = True
while index < len(s)
if n[index]==n[-1-index]
index=1
return True
return False
I'm not really sure where to go from there.
For a list or a string:
seq == seq[::-1]
This is your function, the naive way. Works both with odd and even palindromes, lists and strings:
def is_palindrome(s):
return s == s[::-1]
The other question is, are palindromes only odd or even sequences, or both? I mean should both abccba and abcba match, or just one of them?
You can add a test if you want only odd or even sequences to be considered as a palindromes:
def is_palindrome(s, t='both'):
# only odd sequences can be palindromes
if t=='odd':
if len(s)%2 == 0:
return False
else:
return s == s[::-1]
# only even sequences can be palindromes
elif t=='even':
if len(s)%2:
return False
else:
return s == s[::-1]
# both even or odd sequences can be palindromes
else:
return s == s[::-1]
Only one function, as string are lists of characters. You still can make an alias if your teacher really wants two functions:
def is_list_palindrome(l, t='both'):
return is_palindrome(l, t)