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:
cache.add(char)
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.
-
1\$\begingroup\$ 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. \$\endgroup\$Bent– Bent2016年10月22日 18:08:28 +00:00Commented Oct 22, 2016 at 18:08
2 Answers 2
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.)
(More) Comments
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