- You can change your
if
to just bereturn
. - You should change your
while
to anif
, as it makes no sense for it to bewhile
. - You shouldn't return a string on invalid input, instead you could
raise
aValueError
.
This can get:
def is_anagram(string1, string2):
if len(string1) == len(string2):
return sorted(string1) == sorted(string2)
raise ValueError('The strings are not anagrams they have differing lengths')
However I wouldn't raise
, and so you can just use:
def is_anagram(string1, string2):
return sorted(string1) == sorted(string2)
To answer your questions:
The \$O\$ complexity for your function is not \$O(1)\$. Lets take the different aspects of your function:
len(n)
is \$O(1)\$int == int
is \$O(1)\$sorted(n)
is \$n\log{n}\$str == str
is \$O(n)\$len(a) == len(b)
is \$O(1)\$sorted(a) == sorted(b)
is \$O(\min(a, b) + a\log{a} + b\log{b})\$
Since the function will short circuit if len(a) == len(b)
we know that \$a = b = n\$.
And so the complexity becomes \$O(n + n\log{n})\$. This may be ok to simplify to \$O(n\log{n})\$, as \$O(n + n\log{n}) = O(n(1 + \log{n}))\$
You can however use collections.Countercollections.Counter
to reduce your sorted
complexity to \$O(n)\$. And so keeping the short circuiting your function would be \$O(n)\$, otherwise it would be \$O(a + b)\$. And so to use this you can use:
from collections import Counter
def is_anagram(string1, string2):
return Counter(string1) == Counter(string2)
- I would prefer you use the builtin functions, as it should lead to less code to maintain.