4

I have a dictionary and a word:

check = {'a': 3, 'e': 1, 'p': 2, 'r': 1, 'u': 1, 't': 1}
word = 'rapturerererer'

I'm looking to run a test if all the letters from word are in check. So I need to keep a running count of all the used up letters and check if there are any negatives at the end.

I have code but it always caps out the values at 0 and never returns the negative values:

for letter in word:
    if check.get(letter):
        check[letter] -= 1
print(check)

{'a': 2, 'p': 1, 'r': 0, 'e': 0, 't': 0, 'u': 0}

What I'm expecting is this:

{'a': 2, 'p': 1, 'r': -5, 'e': -4, 't': 0, 'u': 0}

Can anyone explain why it's stopping at 0 for these values?

jpp
  • 159,742
  • 34
  • 281
  • 339
staten12
  • 735
  • 3
  • 9
  • 20
  • 1
    `if 0` evaluates to `False` - change the conditon to `if check.get(letter) is not None` – pault Aug 09 '18 at 16:22

2 Answers2

7
if check.get(letter):
    check[letter] -= 1

if check.get(letter) doesn't only fail if letter is missing; it also fails if the value in the dict is "falsy". None is falsy, and so is 0. Once it hits 0 the test fails and no more decrementing happens.

Use in instead.

if letter in check:
    check[letter] -= 1
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
2

Your error occurs because checking if d.get(x) assesses the nature of the value (i.e. whether it is 0 or False-like) rather than just the existence of the key.

An alternative is to use collections.Counter followed by a dictionary comprehension:

from collections import Counter

check = {'a': 3, 'e': 1, 'p': 2, 'r': 1, 'u': 1, 't': 1}
word = 'rapturerererer'

word_count = Counter(word)

res = {k: check[k] - word_count[k] for k in check}

print(res)

{'a': 2, 'e': -3, 'p': 1, 'r': -5, 'u': 0, 't': 0}

This will work because Counter objects return 0 value for a key which has not been added.

jpp
  • 159,742
  • 34
  • 281
  • 339