Style
Python has a Style Guide called PEP 8. It is definitly worth reading and trying to apply. You'll find various tools to help you if needed.
The main issues are:
- missing whitespace
- indentation does not always use 4 spaces
Once this is fixed, your code looks like:
def palindrome(s):
if s == s[::-1]:
return True
noTest = int(input())
s = []
for _ in range(noTest):
s.append(input())
count = []
for word in s:
letters = []
psub = []
for l in word:
letters.append(l)
if l not in psub:
psub.append(l)
for i in range(len(letters)):
for k in range(i+1, len(letters) + 1):
sub = ('').join(letters[i:k])
# print (i,k,sub)
if palindrome(sub) and sub not in psub:
psub.append(sub)
count.append(len(psub))
for c in count:
print(c)
Implicit return in palindrome
and other improvements
In the palindrome
function, you either return True
or an implicit None when the end of the function is reached. When your functions does return a value in at least one place, it is much clearer to add an explicit return None
. However, it'd probably make more sense to return False
in that case. Trying to add documentation for that function, you would have seen the issue.
Then your function looks like:
def palindrome(s):
""" Return True if string s is a palindrom, False otherwise."""
if s == s[::-1]:
return True
return False
However, this can also be written:
def palindrome(s):
""" Return True if string s is a palindrom, False otherwise."""
return s == s[::-1]
More functions
It would probably worth extracting the code computing the number of palindromic substrings in a function on its own.
It makes the code easier to understand and easier to test (I'll come back to testing later).
Then, your code looks like:
def palindrome(s):
""" Return True if string s is a palindrom, False otherwise."""
return s == s[::-1]
def number_of_palindrom_substrings(word):
""" Return the number of palindrom substrings of string s."""
letters = []
psub = []
for l in word:
letters.append(l)
if l not in psub:
psub.append(l)
for i in range(len(letters)):
for k in range(i+1, len(letters) + 1):
sub = ('').join(letters[i:k])
# print (i,k,sub)
if palindrome(sub) and sub not in psub:
psub.append(sub)
return len(psub)
count = []
for word in s:
count.append(number_of_palindrom_substrings(word))
for c in count:
print(c)
The count
list
Instead of using multiple calls to append
, you could use a list comprehension to define count
:
count = [number_of_palindrom_substrings(word) for word in s]
However, building this list is not even required:
for word in s:
print(number_of_palindrom_substrings(word))
The right data type
Your store unique palindroms in a list. In order to do so, you check if the string is in the list before adding it. You should use a set to make things easier.
def number_of_palindrom_substrings(word):
""" Return the number of palindrom substrings of string word."""
letters = []
psub = set()
for l in word:
letters.append(l)
psub.add(l)
for i in range(len(letters)):
for k in range(i+1, len(letters) + 1):
sub = ('').join(letters[i:k])
if palindrome(sub):
psub.add(sub)
return len(psub)
List of letters is not required
You build a list to contain the successive letters of word
. This is not required, you can perform whatever operation you like directly on word
.
def number_of_palindrom_substrings(word):
""" Return the number of palindrom substrings of string s."""
psub = set()
for l in word:
psub.add(l)
for i in range(len(word)):
for k in range(i+1, len(word) + 1):
sub = ('').join(word[i:k])
if palindrome(sub):
psub.add(sub)
return len(psub)
Then you can initialise psub
with a set comprehension:
psub = set(l for l in word)
or even better, without a list comprehension:
psub = set(word)