views:

1949

answers:

4

Given two dictionaries, d1 and d2, and an integer l, I want to find all keys k in d1 such that either d2[k]<l or k not in l. I want to output the keys and the corresponding values in d2, except if d2 does not contain the key, I want to print 0. For instance, if d1 is

a: 1
b: 1
c: 1
d: 1

and d2 is

a: 90
b: 89
x: 45
d: 90

and l is 90, the output would be (possibly in a different order)

b 89
c 0

What is the best way to do this in Python? I am just starting to learn the language, and so far this is what I have:

for k in d1.keys():
    if k not in d2:
        print k, 0
    else:
        if d2[k]<l:
            print k, d2[k]

This works of course (unless I have a typo), but it seems to me that there would be a more pythonic way of doing it.

A: 

Except for you needing to indent the lines after the "else:", this seems to be a pretty clean way to do what you are looking to do.

Patrick Harrington
ooops i'll fix that thanks
+3  A: 

You can simplify this by using a defaultdict. Calling __getitem__ on a defaultdict will return the "default" value.

from collections import defaultdict
d = defaultdict(int)
print d['this key does not exist'] # will print 0

Another bit that you could change is not to call keys. The dictionary implements iter. It would be preferable to simply write:

for k in d1:
daniel
+7  A: 

Yours is actually fine -- you could simplify it to

for k in d1:
    if d2.get(k, 0) < l:
       print k, d2.get(k, 0)

which is (to me) pythonic, and is pretty much a direct "translation" into code of your description.

If you want to avoid the double lookup, you could do

for k in d1:
    val = d2.get(k, 0)
    if val < l:
        print k, val
dF
+1  A: 

Here is a compact version, but yours is perfectly OK:

from collections import defaultdict

d1 = {'a': 1, 'b': 1, 'c': 1, 'd': 1}
d2 = {'a': 90, 'b': 89, 'x': 45, 'd': 90}
l = 90

# The default (==0) is a substitute for the condition "not in d2"
# As daniel suggested, it would be better if d2 itself was a defaultdict
d3 = defaultdict(int, d2)
print [ (k, d3[k]) for k in d1 if d3[k] < l ]

Output:

[('c', 0), ('b', 89)]
Federico Ramponi
This is really a +1 for daniel
Federico Ramponi