This is my function (says if 2 compared words are anagrams or not):
def are_anagrams(word1, word2):
word1list = list(word1)
word2list = list(word2)
anagramfalse = False
anagramtrue = True
if (word1 == word2):
return anagramfalse
if (word1list.sort()) == (word2list.sort()):
return anagramtrue
else:
return anagramfalse
So this function is returning
are_anagrams("lopped", "poodle")
as True
, for some reason. Can't figure out why. It should be compared the sorted list of letters for each word and returning a False
.
Solution? Mainly just want to know what's wrong.
sort
does not do what you think. Observe:
>>> x = list('lopped')
>>> print(x.sort())
None
Since None == None
is always True, the function always returns True.
Further, the code can be simplified:
def are_anagrams(word1, word2):
return sorted(word1) == sorted(word2)
Sample runs:
>>> are_anagrams("lopped", "poodle")
False
>>> are_anagrams("lopped", "doppel")
True
Notes:
Both sort
and sorted
operate on strings as well as lists. There is no need to convert to lists first.
sorted(word1) == sorted(word2)
evaluates to True or False. Consequentl, the if-then-else
statement can be eliminated.
Phrases can also be considered anagrams of each other. Also, for anagrams, case should generally be ignored. Thus:
def are_anagrams(word1, word2):
return sorted(word1.lower().replace(' ', '')) == sorted(word2.lower().replace(' ', ''))
Thus:
>>> are_anagrams('Lopped', 'Ed Plop')
True
If the words are the same, should they be considered anagrams? If not, then use:
def are_anagrams(word1, word2):
return (word1.lower() != word2.lower()) and sorted(word1.lower().replace(' ', '')) == sorted(word2.lower().replace(' ', ''))
Example:
>>> are_anagrams('Lopped', 'Lopped')
False
>>> are_anagrams('Lopped', 'Old Pep')
True
Here's the issue: wordlist.sort()
will return None
because it does the sorting in place comparing None
to None
will always evaluate to True
and yield falsified results. You should be using sorted()
which instead returns the newly sorted list and then perform the comparison:
def are_anagrams(word1, word2):
word1list = list(word1)
word2list = list(word2)
anagramfalse = False
anagramtrue = True
if (word1 == word2):
return anagramfalse
if (sorted(word1list)) == (sorted(word2list)):
return anagramtrue
else:
return anagramfalse
Apart from that, there are further things to note, first, no need to set explicit names for True
and False
; just return them:
def are_anagrams(word1, word2):
word1list = list(word1)
word2list = list(word2)
if (word1 == word2):
return False
if (sorted(word1list)) == (sorted(word2list)):
return True
else:
return False
Second off, no need to cast the strings to lists with list
, sorted
will take care of that for you automatically by creating a list
from the string, sorting it and then returning it:
def are_anagrams(word1, word2):
if (word1 == word2):
return False
if (sorted(word1)) == (sorted(word2)):
return True
else:
return False
Third off word1 == word2
won't really do much as a "quick check" to exit early; sorting is fast in general, you could drop that all together:
def are_anagrams(word1, word2):
if (sorted(word1)) == (sorted(word2)):
return True
else:
return False
For the final step to make this code as sortest as possible, look at Johns answer; he simply returns the result of comparing the sorted objects. No need to be explicit if your comparison will yield the right value for you. :-)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.