Check if a string is a permutation of a palindrome using Python
Some suggestions:


You strip out spaces, then on the next line check if each character is a space.  The second part is redundant.
The only possible values for freq % 2 are 0 and 1, so num_odd = sum(1 for char, freq in Counter(data).items() if char != ' ' and freq % 2 == 1) can be simplified as num_odd = sum(freq % 2 for Counter(data).values())
If num_odd is 0, then there must be an even number of elements. If num_odd is 1, then there must be an odd number of elements.  So really all you care about is if there is more than 1 odd count.
You can return the results of expressions directly.  So something like return x &lt; y is simpler than using an if test and manually returning True or False depending on the outcome.
I would put the replace first since that reduces the number of characters that lower has to operate over (although this is probably a silly negligible micro optimization).


So the code can be simplified to:

from collections import Counter


def is_palindrome_permutation(data: str) -&gt; bool:
    """Given a string, check if it is a permutation of a palindrome."""
    data = data.replace(' ', '').lower()
    return sum(freq%2 for freq in Counter(data).values()) &lt; 2


One more thing you could do is put the Counter on the first line.  I think this hurts readability a bit, but does mean that your modified data can be garbage collected right away.  There is no point doing this with .values(), though, since this is just a view into the Counter object, so the Counter object has to be kept in memory.

from collections import Counter


def is_palindrome_permutation(data: str) -&gt; bool:
    """Given a string, check if it is a permutation of a palindrome."""
    data = Counter(data.replace(' ', '').lower())
    return sum(freq%2 for freq in data.values()) &lt; 2