Hackerrank Python3 Hash Tables: Ransom Note and dictionary comprehension

Viewed 175

I am learning Python, and i use it to solve tasks on HackerRank. I have the problem with exercise Hash Tables: Ransom Note. I have written that code:

def checkMagazine(magazine, note):
mag_h = {}
#mag_h = {i: mag_h[i] + 1 if i in mag_h else 1 for i in magazine}
for i in magazine:
    if i in mag_h:
        mag_h[i] += 1
    else:
        mag_h[i] = 1
for i in note:
    if (not i in mag_h) or (mag_h[i] < 1):
        print("No")
        return
    else:
        mag_h[i] -= 1
print("Yes")
return

When i use dictionary comprehension (commented line), my code does not pass all test, but when i use for instruction to create the dictionary, it does. Is it not equivalent? Could You tell me why?

Sorry for my English :(

1 Answers

You cannot referenze the varible your dict comp is assigned to inside itself - it does not update "iteratively".

It is easy to show:

magazine = ["T","T","T","o"]
mag_h = {}
# this references the empty dict mag_h = {} all the time and never finds any key in it
mag_h = {i: mag_h[i] + 1 if i in mag_h else 1 for i in magazine}

print(mag_h)

Output:

{'T': 1, 'o': 1}

Versus:

mag_h = {}
for i in magazine:
    if i in mag_h:
        mag_h[i] += 1
    else:
        mag_h[i] = 1
print(mag_h)

Output:

{'T': 3, 'o': 1}

You can solve this task easily using collections.Counter or collections.defaultdict(int) to get more performance then the for-loop.

from collections import Counter

def checkMagazine(magazine, note):
    mag_count = Counter(magazine)
    note_count = Counter(note)

    return all(occ <= mag_count.get(key,0) for key,occ in note_count.items())

m, n = map(int, input().strip().split())
magazine = input().strip().split()
ransom = input().strip().split()
print("Yes" if checkMagazine(magazine, ransom) else "No") 
Related