On Sat, Nov 20, 2010 at 4:00 AM, Steven D'Aprano <st...@remove-this-cybersource.com.au> wrote: > On Sat, 20 Nov 2010 01:11:53 -0500, Steve Holden wrote: > >> On 11/19/2010 8:58 PM, Jin Yi wrote: >>> so i came up with a diff method to compare 2 dicts. > [...] >> A PEP *and* some explanation of why you would want such an obscure piece >> of code built in to the dict object, yes. > > You've never wanted to see how two dicts differ, as well as the fact that > they do? I frequently find myself wanting to see why two dicts that > should be equal aren't, especially for testing and debugging. > > I use this function: > > def dict_diffs(a, b): > """dict_diffs(adict, bdict) -> (amissing, bmissing, different) > > Returns sets (amissing, bmissing, different) such that: > > amissing = keys missing from adict compared to bdict > bmissing = keys missing from bdict compared to adict > different = keys in both adict and bdict but with different values > > >>> dict_diffs({1:0, 2:0, 3:0}, {1:1, 2:0, 4:0}) > (set([4]), set([3]), set([1])) > > """ > from collections import Mapping > if not isinstance(a, Mapping) and isinstance(b, Mapping): > raise TypeError('arguments must both be mappings') > amissing, bmissing, different = set(), set(), set() > for key, value in a.items(): > if key not in b: > bmissing.add(key) > elif value != b[key]: > different.add(key) > for key, value in b.items(): > if key not in a: > amissing.add(key) > return (amissing, bmissing, different)
Add me to this group. I frequently use some homebrew set operations on dictionaries. My (stupid) implementation: #! /usr/bin/env python3 class AugmentedDict(dict): def __and__(self, other): """Dictionary intersection operation""" return AugmentedDict(self.items() & other.items()) def __or__(self, other): """Dictionary union operation""" union = self.items() | other.items() merged_union = AugmentedDict(union) if len(union) != len(merged_union): err = 'Cannot take union of non-pairwise disjoint dictionaries' raise Exception(err) return merged_union def __sub__(self, other): """Dictionary difference operation""" return AugmentedDict(self.items() - other.items()) def __xor__(self, other): """Dictionary symmetric difference operation""" return AugmentedDict(self.items() ^ other.items()) if __name__ == "__main__": # demonstrate the behavior of AugmentedDict a = AugmentedDict({'a': 1, 'b': 2, 'c': 3}) b = AugmentedDict({'b': 2, 'c': 3}) c = AugmentedDict({'a': 1}) assert( (a|(b|c)) == (b|(a|c))) assert( (a&(b&c)) == (b&(a&c))) assert( (b&c) == (c&b)) assert( (a - b) == c) assert( (a ^ b) == ((a-b) | (b-a))) Truth be told, I was under the impression that this was actually going to be a part of dictionary behavior at some point, maybe I was thinking of the .items() behavior. Geremy Condra -- http://mail.python.org/mailman/listinfo/python-list