3

In the follwing code I wanted to use integers as keys in a dict:

import itertools N = {} for a,b,c,d in itertools.product(range(100), repeat=4): x = a*a + c*c y = a*b + c*d z = b*b + d*d s = x + y + y + z N[s] += 1 print N 

I get a KeyError: 0 at N[s] += 1. Why is it so? The documentation says that

strings and numbers can always be keys

The wiki gives an explanation on KeyError:

Python raises a KeyError whenever a dict() object is requested (using the format a = adict[key]) and the key is not in the dictionary.

What I want to do is to build a dict with yet-unknown keys (they are computed on the fly) and keep a counter for them. I have done that in the past (with strings as keys) so what did I did wrong this time? (I know - this must be super obvious but after some time glaring at this complicated code I need help :))

3
  • 3
    Your key is not defined so you get an error. (you can't add 1 to something that doesn't exist). You probably want to use Counter, from collections import Counter; N = Counter() Commented Oct 8, 2013 at 7:31
  • Thanks - I was focusing on the existence of the key and not the value. Commented Oct 8, 2013 at 7:50
  • Your question is fine. You provided actual code, listed the error you received and made an attempt and deciphering the error. If people don't like your question they should leave a comment as to why. Commented Oct 8, 2013 at 7:56

3 Answers 3

5

Use defaultdict

import itertools from collections import defaultdict N = defaultdict(int) for a,b,c,d in itertools.product(range(100), repeat=4): x = a*a + c*c y = a*b + c*d z = b*b + d*d s = x + y + y + z N[s] += 1 print N # answer is too long to include here 
Sign up to request clarification or add additional context in comments.

Comments

1

In your first iteration, N is empty, however you are attempting to access N[0]

You can fix this particular problem with

if s in N: N[s] += 1 else: N[s] = 0 # or 1 or whatever 

But as @monkut says in the comments you should use a Counter

1 Comment

Thanks - I did not know Counter, it indeed simplifies the code.
1

Counter is best because it has methods to analyze the results, but you can also use a defaultdict:

from collections import defaultdict N = defaultdict(int) 

If a key is not present the value will be initialized to the default for int, which is zero.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.