Given below is the code to check if a list is a palindrome or not. It is giving correct output for 983. Where am I going wrong?
def palindrome(num):
flag=0
r=num[::-1]
for i in range (0, len(num)-1):
if(r[i]==num[i]):
flag=1
else:
flag=0
return flag
You should return as soon as there is a mismatch. Also, you just need to iterate till half the length:
def function(...):
...
for i in range (0, (len(num) + 1) / 2):
if r[i] != num[i]:
return False
return True
BTW, you don't need that loop. You can simply do:
def palindrome(num):
return num == num[::-1]
This would be easier:
def palindrome(num):
if num[::-1] == num:
return True
else:
return False
Your for loop checks all pairs of characters, no matter if it found mismatch or not. So, in case of string '38113' it will return True, because the flag variable will be set to True after the check for equality of last digit in '38113' and its reversed version '31183' (both equal to 3, while the string isn't a palindrome).
So, you need to return False right after you've found mismatch; if you checked all the characters and didn't find it - then return True, like so:
def palindrome(num):
r = num[::-1]
for i in range (0, len(num)-1):
if(r[i] != num[i]):
return False
return True
Also, as someone pointed out it'll be better to use python's slices - check out the documentation.
Just for the record, and for the ones looking for a more algorithmic way to validate if a given string is palindrome, two ways to achieve the same (using while and for loops):
def is_palindrome(word):
letters = list(word)
is_palindrome = True
i = 0
while len(letters) > 0 and is_palindrome:
if letters[0] != letters[-1]:
is_palindrome = False
else:
letters.pop(0)
if len(letters) > 0:
letters.pop(-1)
return is_palindrome
And....the second one:
def is_palindrome(word):
letters = list(word)
is_palindrome = True
for letter in letters:
if letter == letters[-1]:
letters.pop(-1)
else:
is_palindrome = False
break
return is_palindrome
str1=str(input('enter string:'))
save=str1
revstr=str1[::-1]
if save==revstr:
print("string is pailandrom")
else:
print("not pailadrom")
# We are taking input from the user.
# Then in the function we are reversing the input i.e a using
# slice [::-1] and
# storing in b
# It is palindrome if both a and b are same.
a = raw_input("Enter to check palindrome:")
def palin():
#Extended Slices to reverse order.
b = a[::-1]
if a == b:
print "%s is palindrome" %a
else:
print "%s is not palindrome" %a
palin()
this would be much easier:
def palindrome(num):
a=num[::-1]
if num==a:
print (num,"is palindrome")
else:
print (num,"is not palindrome")
x=input("Enter to check palindrome:")
palindrome(x)
Here in my opinion is the most elegant:
def is_palindrome(s):
if s != '':
if s[0] != s[-1]:
return False
return is_palindrome(s[1:-1])
return True
it's also the same code in the is_palindrome() function:
pip install is-palindrome
>>> from is_palindrome import is_palindrome
>>> x = "sitonapanotis"
>>> y = is_palindrome(x)
>>> y
True
Take care to note the hyphen vs underscore when installing vs. importing
a="mom"
b='mom'[::-1] # reverse the string
if a==b: # if original string equals to reversed
print ("palindrome ")
else:
print ("not a palindrome ")
def palindrome(a):
a=raw_input('Enter :')
b=a[::-1]
return a==b
Related
I'm a begginer in python and i wanted to know how can i restrict characters after another, in my case, after a number.
In this code i want the user to give me a couple of characters, like "SDK70" and print is as valid.
But if the user inputs "SDK7S0" it will print it as invalid.
How can i do this? This is my code so far:
str = input("str here: ")
while len(str) <= 6 and len(str) >= 2:
if str[0:2].isupper() == True:
return str
# if there is a number, return false if after the number there's a let
Try this:
def input_string():
x = input('str here: ')
if 2 <= len(x) <= 6:
number = False
for i in range(len(x)):
if i < 2:
if not x[i].isupper():
return False
else:
if not number and x[i] in [str(a) for a in range(10)]:
number = True
elif number:
if x[i] not in [str(a) for a in range(10)]:
return False
return True
return False
I'm not sure to understand very well your requirements but here are my thoughts.
First of all, I don't see any function (def) here so return doesn't mean a lot. but assuming we are in a function named "check_str".
Here is a solution that I get from seeing your question
def check_str(str):
if len(str) < 2 or len(str) > 6: # Length check
return False
allowed_characters_after_numbers = ['S', 'D', 'K', '7', '0']
previous_letter_was_number = False
for letter in str:
if previous_letter_was_number == True:
if letter not in allowed_character_after_numbers:
return False
if letter.isnumeric(): # Test is the letter is a number
previous_letter_was_number = True
else:
previous_letter_was_number = False
else:
return True
str = input("str here: ")
print("str is good : ", check_str(str))
I not sure if this it fits your case, but you could just check if the string has a number, and then check if the next characters are also:
word = input()
hasNumber = False
for letter in word:
if letter.isnumeric():
hasNumber = True
elif hasNumber:
return False
return True
So I'm trying to count unique letter in this function. If their are unique letters return True if there isn't return False. In the word 'Programming'
there are two r's and two m's and two g's. Its return True where the actual answer is False? Is my logic wrong here?
def unique_chars_in_string(input_string):
unique_chars = {}
if input_string == "":
return True
for letter in input_string:
if letter in unique_chars:
unique_chars[letter]+=1
else:
unique_chars[letter]=1
for k in unique_chars:
if unique_chars[k] > 1:
return False
else:
return True
print(unique_chars_in_string('Programming'))
According to your algorithm, you're just checking the first character of the string. And not the entire string.
This block of code has erroneus logic:
for k in unique_chars:
if unique_chars[k] > 1:
return False
else:
return True
You don't need that else condition inside the for loop.
Try this instead:
def unique_chars_in_string(input_string):
unique_chars = {}
if input_string == "":
return True
for letter in input_string:
if letter in unique_chars:
unique_chars[letter]+=1
else:
unique_chars[letter]=1
for k in unique_chars:
if unique_chars[k] > 1:
return False
return True
print(unique_chars_in_string('Programming'))
So, if any character has more than 1 count, your code will return false else it will return true.
Also, check Jean-François Fabre's answer to this problem, it is a short and sweet Pythonic implementation.
Happy Coding! :)
if you want to check if all letters occur only once use all
return all(k == 1 for k in unique_chars.values())
that will avoid to return too soon a result when you haven't scanned the rest of the letters.
Also consider counting your letters with collections.Counter which is a specialized dictionary made for counting hashable elements:
unique_chars = collections.Counter(input_string)
so combining in one line:
return all(k == 1 for k in collections.Counter(input_string).values())
That said, we're missing the point. If we need to check if a word has non-duplicate letters this can be done without counting using a set:
return len(input_string) == len(set(input_string))
for k in unique_chars:
if unique_chars[k] > 1:
return False
else:
return True
This is your problem. This checks if any value in unique_chars is greater than one, or if the first value is one or less. You should instead do:
for k in unique_chars:
if unique_chars[k] > 1:
return False
return True # since this is after the for loop, it only runs if
# no character has a count greater than one.
Alternatively this can be made more efficient with a set.
seen = set()
for c in input_string:
if c in seen:
return False
seen.add(c)
return True
You return too early in the loop when you encounter the first unique character. You only know all are unique at the end of the loop:
def unique_chars_in_string(input_string):
unique_chars = {}
for letter in input_string:
if letter in unique_chars:
unique_chars[letter]+=1
else:
unique_chars[letter]=1
for k in unique_chars:
if unique_chars[k] > 1:
return False # not all are unique -> return early
# but only when all have been checked, can you know for sure all are
return True
This whole function can be shortened, using collections.Counter and all, but maintaining the underlying algorithm:
from collections import Counter
def unique_chars_in_string(input_string):
return all(v==1 for v in Counter(input_string).values())
Or even simpler:
def unique_chars_in_string(input_string):
return len(input_string) == len(set(input_string))
s = 'Programming'
a = [True for i in s if s.count(i) > 1]
if any(a):
print(False)
else:
print(True)
I am trying to figure out why the following code doesn't work.
The code seems correct to me but it always returns True.
import string
lower_alpha = string.ascii_lowercase
def no_repeat_loweralpha_1 (string):
for i in range(len(string)):
if not string[i] in lower_alpha: return False
if string[i] in string[:i]: return False
else: return True
string = 'ab/!34cda56aaa1..,efgahijk'
print no_repeat_loweralpha_1(string)
# OUTPUT: True
Here is another variant of the code which has the same problem:
def no_repeat_loweralpha_2(string):
for i in range(len(string)):
if string[i] < 'a' or string[i] > 'z' : return False
if string[i] in string[:i]: return False
else: return True
string = 'ab/!34cda56aaa1..,efgahijk'
print no_repeat_loweralpha_2 (string)
# OUTPUT: True
Edit:
Is there a shorter way to write a function that achieves this? How can I write the function using lambda?
A more pythonic version would have been something like this:
return s.isalpha() and s.islower() and len(s) == len(set(s))
Here's another approach. Collect all unique lowercase letters, and check the length against your original:
def no_repeat_lower_alpha(foo):
s = set()
for i in foo:
if i.islower():
s.add(i)
return len(s) == len(foo)
try the following code
def lower_and_duplicate(str_test):
dict_found_chars = {}
for char in str_test:
if not char.islower():
return False
if dict_found_chars.has_key(char):
return False
else:
dict_found_chars[char] = 1
return True
print lower_and_duplicate("aAsdfsdfsdf")
print lower_and_duplicate("aasdfsdfsdf")
print lower_and_duplicate("abcdefgh")
The dict checks for duplicates and we test for lowercase at each step
Shorter version:
all(x in lower_alpha and s.count(x) < 2 for x in s)
If any char is not lowercase or the count is > 1 it will return False
You could remove the string import with:
all( x.isalpha() and x.islower() and s.count(x) < 2 for x in s)
So I recently implemented a code that checks a word to see if it's a palindrome.
def isPalindrome():
string = input('Enter a string: ')
string1 = string[::-1]
if string[0] == string[(len(string)-1)] and string[1:(len(string)-2)] == string1[1:(len(string)-2)]:
print('It is a palindrome')
else:
print('It is not a palindrome')
isPalindrome()
I was wondering if anyone could give me tips on simplifying the code.
Edit - If I were to make the function an iterative function with the statements string == string1, how would I stop the endless while loop? Would I need a count to stop the while loop?
No need for such complex conditional. You already have a reversed string (string[::-1]).
All you need to do is this:
def isPalindrome():
string1 = input('Enter a string: ')
string2 = string1[::-1]
if string1 == string2:
return 'It is a palindrome'
return 'It is not a palindrome'
isPalindrome()
(by the way don't use string as a variable name. That's the name of a built-in module)
It's better to return the strings instead of printing them. That way your function will not return None (preventing some stuff that could happen later)
You can do it in a one liner:
return "Is a palindrome" if string == string[::-1] else "Not a palindrome"
Sample script:
>>> string = "stanleyyelnats"
>>> print "Is a Palindrome" if string == string[::-1] else "Not a palindrome"
>>> Is a Palindrome
You can also do this (although its slower):
print "Is a Palindrome" if string == ''.join(reversed(string)) else "Not a palindrome"
Also, use raw_input and not input. Because input will be evaluated. Let me show you an example:
Script
inp = input("Evaluate ")
print inp
Run
Evaluate "cheese" + "cake"
cheesecake
Here is a simple solution in just 1 LINE.
plandrom = lambda string: True if string == string[::-1] else False
Please check this algorithm,
def is_palindrome(n):
m = len(n)/2
for i in range(m):
j = i + 1
if n[i] != n[-j]:
return False
return True
print is_palindrome('malayayalam')
So, I just got into learning python and I have been trying to these exercises, #8. Though I see that a lot of these answers are creating a new reverse string(which adds a memory overhead) and comparing both strings, I thought I could utilize lesser memory by doing this:
def is_palindrome(s):
l=len(s)
list_s=list(s)
for i in range(0,l):
if(list_s[i] !=list_s[l-i-1]):
return False
else:
return True
You can use a print statement to verify.
All I am doing is comparing the first index to the last and the second index to the second last and so on.
Hope that helps.
Check Counter from collections
from collections import Counter
def is_palindrome(letters):
return len([v for v in Counter(letters).values() if v % 2]) <= 1
Here is another solution I came up with:
###Piece of code to find the palindrome####
def palindrome():
Palindromee = input("Enter the palindrome \t:")
index = 0
length = len(Palindromee)
while index < length:
if Palindromee[0] == Palindromee[-1] :
index +=1
print ("Palindrome worked as expected")
palindrome()
Simple way to write palindrome
a=raw_input("Enter the string : ") # Ask user input
b= list(a) # convert the input into a list
print list(a)
b.reverse() # reverse function to reverse the
# elements of a list
print b
if list(a) == b: # comparing the list of input with b
print("It is a palindrome")
else:
print("It is not a palindrome")
we could use reverse String function to verify Palindrome:
def palindrome(s):
str=s[::-1]
if s==str:
return True
else:
return False
palindrome('madam')
you can as well try this
def palindrome(str1):
return str1==str1[::-1]
print(palindrome(str1)
the answer above returns a boolean according to the string given
if it is a palindrome prints true else false
I'd like to know how do I check if an input is a palindrome with a while loop, using Python.
Thanks:
i tried this
i = 0
n = len(msg_list)
while i < n:
palindrome = msg_list[i]
if palindrome == msg_list[-1]:
print("Palindrome? True")
msg_list.pop(-1)
else:
print("Palindrome? False")
i=i+1
but at the end I receive an error message that the list index is out of range
You don't need to iterate till the end, but only till the middle character. And compare every character to the character at the same index when counted in reverse:
s = "abcca"
length = len(s)
i = 0
while i < length / 2 + 1:
if s[i] != s[-i - 1]:
print "Not Palindrome"
break
i += 1
else:
print "Palidrome"
else part of the while loop is executed, when the loop completes its iteration without any break.
Alternatively, if you can use anything else than a while loop, then this task is just of single line in Python:
if s == s[::-1]:
print "Palindrome"
Oh, it became two lines.
With a while loop
import string
palin = 'a man, a plan, a canal, panama'
def testPalindrome(in_val):
in_val = in_val.lower()
left, right = 0, len(in_val) - 1
while left < right:
char_left, char_right = '#', '#'
while char_left not in string.lowercase:
char_left = in_val[left]
left += 1
while char_right not in string.lowercase:
char_right = in_val[right]
right -= 1
if char_left != char_right:
return False
return True
print testPalindrome(palin)
Without
>>> palindrome = 'a man, a plan, a canal, panama'
>>> palindrome = palindrome.replace(',', '').replace(' ', '')
>>> palindrome
'amanaplanacanalpanama'
>>> d[::-1] == d
True
A short solution using reversed:
for c, cr in s, reversed(s):
if c != cr:
print("Palindrome? False")
break
else:
print("Palindrome? True")
Another way using a while loop. Once two characters don't match, the while loop stops, so it's quite efficient but of course not the best way to do it in Python.
def palindrome(word):
chars_fw = list(word)
chars_bw = list(reversed(word))
chars_num = len(word)
is_palindrome = True
while chars_num:
if chars_fw[chars_num-1] != chars_bw[chars_num-1]:
is_palindrome = False
break
chars_num -= 1
return is_palindrome
Figured I would add another alternative for people still viewing this question. It uses a while loop, and is reasonably concise (although, I still prefer the if word = word[::-1] approach.
def is_palindrome(word):
word = list(word.replace(' ', '')) # remove spaces and convert to list
# Check input
if len(word) == 1:
return True
elif len(word) == 0:
return False
# is it a palindrome....
while word[0] == word[-1]:
word.pop(0)
word.pop(-1)
if len(word) <= 1:
return True
return False
word = "quiniuq"
pairs = zip(word,reversed(word))
a,b = next(pairs)
try:
while a == b:
a,b = next(pairs)
return False # we got here before exhausting pairs
except StopIteration:
return True # a == b was true for every pair
The use of a while loop here is contrived, but it will consume the whole list and perform the test.
If a while loop wasn't a requirement, one would do: all(a == b for a,b in zip(word,reversed(word)))