ignored_keys = ('hash', 'timestamp') def filter_items(d): ''' Filter out keys when returning items() ''' l = [] # Ensure we return sorted tuples for k, v in sorted(d.items()): if k not in ignored_keys: l.append((k, v)) return l def is_update_required(original, proposed): ''' Compare two data-structures ''' if type(original) != type(proposed): print "Datatypes don't match: {0} vs {1}".format(type(original), type(proposed)) return True if isinstance(original, list) or isinstance(original, tuple): if len(original) != len(proposed): print "Lengths don't match: {0} vs {1}".format(len(original), len(proposed)) return True for a, b in zip(original, proposed): if is_update_required(a, b): return True elif isinstance(original, dict): # Turn dictionaries into list of tuples, and re-evaluate if is_update_required(filter_items(original), filter_items(proposed)): return True else: # Works for sets, integers, strings, ... if original != proposed: print "Values don't match: {0} vs {1}".format(original, proposed) return True return False