2
def are_anagrams(sent_one,sent_two):
    sent_one=sent_one.replace(" ","")
    sent_one=sent_one.lower()
    sent_two=sent_two.replace(" ","")
    sent_two=sent_two.lower()
    dict_of_one={}
    dict_of_two={}
    for one in sent_one:
        if one not in dict_of_one:
            dict_of_one.setdefault(one,1)
        else:
            dict_of_one[one]+=1
    for second in sent_two:
        if second not in dict_of_two:
            dict_of_two.setdefault(second,1)
        else:
            dict_of_two[second]+=1
    print(dict_of_one)
    print(dict_of_two)
    for k,v in dict_of_one.items():
        if k in dict_of_two and dict_of_two[k]==v:
            return True
        else:
            return False

print(are_anagrams("Elvis", "Lives"))
print(are_anagrams("Elvis", "Live Viles"))
print(are_anagrams("Eleven plus two", "Twelve plus one"))
print(are_anagrams("Hot Water","Worth Coffee"))

Hi, I want to check two dictionaries are the same or not. I tried to do the end of the code, but I couldn't do it. Could you show me a way to do it?

def are_anagrams(first_word, second_word):
    first_word = first_word.lower()
    second_word = second_word.lower()
    first_word = first_word.replace(' ', '')
    second_word = second_word.replace(' ', '')
    letters = []
    for char in first_word:
        letters.append(char)
    for char in second_word:
        if char not in letters:
            return False
        letters.remove(char)
    return len(letters) == 0

this is the second approach...

def are_anagrams(first_word, second_word):
    first_word = first_word.lower()
    second_word = second_word.lower()
    first_word = first_word.replace(' ', '')
    second_word = second_word.replace(' ', '')

    first_word_list=list(first_word)
    first_word_list.sort()
    first_word="".join(first_word_list)

    second_word_list=list(second_word)
    second_word_list.sort()
    second_word="".join(second_word_list)

    if hash(second_word)==hash(first_word):
        return True
    return False

print(are_anagrams("Elvis", "Lives"))
print(are_anagrams("Elvis", "Live Viles"))
print(are_anagrams("Eleven plus two", "Twelve plus one"))
print(are_anagrams("Hot Water","Worth Coffee"))

the third approach to this code uses hash codes. I try to add more ways to solve it...

Lima
  • 141
  • 1
  • 1
  • 6
  • 1
    `dict_of_one == dict_of_two `? – Dani Mesejo Oct 28 '21 at 08:53
  • I think this is answered here too: [compare two dicts](https://stackoverflow.com/questions/4527942/comparing-two-dictionaries-and-checking-how-many-key-value-pairs-are-equal) – pyzer Oct 28 '21 at 08:55
  • thank you Dani, it worked, but I want to ask a question about dictionaries. when we do this(dict_of_one == dict_of_two), is it compare all keys and values at the same time? – Lima Oct 28 '21 at 08:57
  • you are right @pyzer I focused on the code blocks but it was the head of the block. – Lima Oct 28 '21 at 09:01

3 Answers3

1

You can simplify this, the main point being the equality check of the two dictionaries:

def are_anagrams(sent_one,sent_two):
    sent_one = sent_one.replace(" ","").lower()
    sent_two = sent_two.replace(" ","").lower()
    dict_of_one = {}
    dict_of_two = {}
    for one in sent_one:
        dict_of_one[one] = dict_of_one.get(one, 0) + 1
    for two in sent_two:
        dict_of_two[two] = dict_of_two.get(two, 0) + 1
    return dict_of_one == dict_of_two 

are_anagrams("Elvis", "Lives")
# True
are_anagrams("Elvis", "Live Viles")
# False
are_anagrams("Eleven plus two", "Twelve plus one")
# True
are_anagrams("Hot Water","Worth Coffee")
# False

But then again, all of that can be shortened:

from collections import Counter

def are_anagrams(sent_one,sent_two):
    c1 = Counter(sent_one.lower().replace(" ", ""))
    c2 = Counter(sent_two.lower().replace(" ", ""))
    return c1 == c2

The usage of Counter (a dict subclass) makes you life so much easier.

user2390182
  • 72,016
  • 6
  • 67
  • 89
1

If you don't have to use a dictionary, it would be easier to use lists:

def split(word):
    return [char for char in word]

def are_anagrams(one, two):
    newOne = split(one.replace(" ","").lower())
    newTwo = split(two.replace(" ","").lower())
    for item in newTwo[:]:
        if item in newOne:
            newOne.remove(item)
            newTwo.remove(item)
    if newOne == [] and newTwo == []:
        return True
    return False

print(are_anagrams("Elvis", "Lives")) # True
print(are_anagrams("Elvis", "Live Viles")) # False
print(are_anagrams("Eleven plus two", "Twelve plus one")) # True
print(are_anagrams("Hot Water","Worth Coffee")) # False

Note the line for item in newTwo[:] has the [:] to stop the for loop breaking because we are deleting items in newTwo. Adding [:] clones the list, meaning it doesn't change when we change the actual newTwo variable.

Dan P
  • 786
  • 7
  • 18
  • Why should the second example be `True`? – user2390182 Oct 28 '21 at 09:07
  • Ahh, good point, my bad, give me a second to fix it! – Dan P Oct 28 '21 at 09:09
  • `are_anagrams("Elvis", "Live Viles")` is still true – user2390182 Oct 28 '21 at 09:11
  • Yeah give me a second, fixing it now. I've only check if one of the lists is empty, not both. – Dan P Oct 28 '21 at 09:13
  • I'm afraid, this approach is algorithmically flawed with the nested loops and the repeated list removal both making it quadratic when this should be linear. – user2390182 Oct 28 '21 at 09:14
  • If that's a concern to the OP, then they can choose not to use my suggestion. But my doesn't require an imported module, and the execution time of the code was not mentioned as a requirement, so its personal preference. – Dan P Oct 28 '21 at 09:19
0

You don't have to overcomplicate things. To check for anagrams, all you need to do is to check whether the two sorted strings are equal.

def anagrams(a, b):
    a, b = [sorted(i.lower().replace(" ", ""))
            for i in (a, b)]
    
    return a == b

Output

Let's do a few test cases on our anagrams function.

>>> anagrams("Elvis", "Lives")
True
>>> anagrams("Elvis", "Live Viles")
False
>>> anagrams("Eleven plus two", "Twelve plus one")
True
>>> anagrams("Hot Water", "Worth Coffee")
False

It worked as expected. Also, this function is fast in terms of time complexity because it depends on the complexity of the sorting algorithm.

Troll
  • 1,895
  • 3
  • 15
  • 34