1

I have searched the previous posts and have not found one where the person asking is doing quite what I'm trying to do:

I am trying to look through two separate dictionaries and find instances where the keys are the same, but the values are different. The dictionaries are not the same size. When I find matching keys that have different values, I want to add just the keys to a list as I will not need the values anymore.

Right now I am doing this. It is horribly inefficient, but is ok for 200-ish items. I have some dictionaries that are over 200,000 items, though, and that is where this becomes a major problem:

    for sourceKey, sourceValue in sourceDict.iteritems():
         for targetKey, targetValue in targetDict.iteritems():
              if targetKey == sourceKey:
                   if targetValue != sourceValue:
                        diffList.append(sourceKey)

Is there a way to do this at all? I am using Python 2.6.

3 Answers3

3
for key in set(sourceDict).intersection(targetDict):
    # Now we have only keys that occur in both dicts
    if sourceDict[key] != targetDict[key]:
        diffList.append(key)

As DSM noted in his (now deleted) answer, you can do this with a list comprehension or generator:

(k for k in set(sourceDict).intersection(targetDict) if sourceDict[key] != targetDict[key])
kojiro
  • 74,557
  • 19
  • 143
  • 201
  • Hmmph. Seven seconds you beat me by! I don't think you need to call `.keys()`, though-- that will create an unnecessary intermediate list. – DSM Apr 09 '13 at 03:13
  • @DSM noted. I'm actually a little surprised there isn't a duck-typing mechanism for treating a dict's keys like a set, since they're next-of-kin anyway. – kojiro Apr 09 '13 at 03:15
  • 1
    Actually, these days calling `.keys()` gives you a `dict_keys()` object, and `a.keys() & b` does what you'd think it does! [We're working with 2.6 here, though, so no fun.] – DSM Apr 09 '13 at 03:18
  • Fantastic! I didn't expect an answer in such a short period of time. Thank you both very much! As for the answer provided by DSM, as well as Ranjan, how would I get what is returned into the diffList? Does that code return another dictionary? – user2259908 Apr 09 '13 at 03:56
  • @user2259908 With parens it's a *generator expression*, which means it returns a generator. A generator lazily yields each value in it when you call `next()` on it. With square brackets it's a *list comprehension*, which means it returns a list. As a list, the values are calculated immediately, and those values are stored in memory. http://stackoverflow.com/questions/47789/generator-expressions-vs-list-comprehension – kojiro Apr 09 '13 at 12:09
0
[k for k in source_dict if target_dict.get(k, object()) != source_dict[k]]
jamylak
  • 128,818
  • 30
  • 231
  • 230
0

1-liner: [key for key in set(sourceDict).intersection(targetDict) if sourceDict[key] != targetDict[key]]

rongenre
  • 1,334
  • 11
  • 21