# Check if a string is a permutation of a palindrome

I see a couple of these on codereview but I was hoping my way hasn't yet been encountered:

def is_palindrome_permutation(strng):
cache = set()
for char in strng.lower():
if not char.isalpha():
continue
if char in cache:
cache.remove(char)
else:

return len(cache) <= 1


Instead of maintaining any counts of characters to check for oddness or evenness, simply add and remove characters from a set. A character repeated an even number of times will be removed from the set; a character repeated an odd number of times will remain in the set. If the final set has a length less than or equal to one, it is a permutation of a palindrome.

• I would call the function is_anagram_of_palindrome. Does it handle utf-8 or just a..z? You might want to state in a comment what you consider legal characters.
– Bent
Oct 22, 2016 at 18:08

# Documentation

You should definitely add a docstring. It took me a few seconds to figure out was was going. Make sure to add some examples in the docstring as well.

# Naming

The name cache may not be the best name. Why? Let's look at the definition of cache:

is a hardware or software component that stores data so future requests for that data can be served faster

I don't really believe you use cache to serve stuff faster. I believe odd_occuring_letters is a better idea. (I don't like long names, maybe challenge yourself to a shorter name? Maybe odd_letters? Think about it.)

Even then, odd_occuring_letters isn't the most descriptive name, so you should include some comments as to what your code does. Don't over do it though.

Remember saying something like:

# Check the length of odd_occuring_letters is less than or equal to one.
return len(odd_occuring_letters) <= 1


Is not good. But saying:

# A word can have at most 1 odd character and still be palindrome.
return len(odd_occuring_letters) <= 1


explains to me why you return the length compared to one.

You can take advantage of the set.symmetric_difference_update() operation, which does exactly your conditional add/remove.

def is_palindrome_permutation(s):
unpaired_chars = set()
for char in s.lower():
if char.isalpha():
unpaired_chars ^= set(char)
return len(unpaired_chars) <= 1