Python: How can one verify that dict1 is only a subset of dict2? Values are all int and within scope

Question:

I’m trying to build some efficient code that can tell if one dict is a subset of another. Both dicts have string keys and int values. For dict1 to be considered a subset, it can not contain any unique keys and all values must be less than or equal to the equivalent key’s value in dict2.

This almost worked:
test_dict.items() <= test_dict2.items() until I tested it here:

test_dict = {
    'a':1,
    'c':2
}

test_dict2 = {
    'a':1,
    'b':2,
    'c':3
}

test_dict.items() <= test_dict2.items()

False

I did get something working, but I dont know how efficient it really is

def test(request_totals, mongo_totals, max_limit=100):
    outdated = dict()
    
    sharedKeys = set(request_totals.keys()).intersection(mongo_totals.keys())
    unsharedKeys = set(request_totals) - set(mongo_totals)
    
    # Verifies MongoDB contains no unique collections
    if set(mongo_totals) - set(request_totals) != set():
        raise AttributeError(f'''mongo_totals does not appear to be a subset of request_totals. 
                            Found: {set(mongo_totals) - set(request_totals)}''')
    
    # Updates outdated dict with outdated key-value pairs representing MongoDB collections
    for key in sharedKeys:
        if request_totals[key] > mongo_totals[key]:
            outdated.update({key : range(mongo_totals[key], request_totals[key])})
        elif request_totals[key] < mongo_totals[key]:
            raise AttributeError(
                f'mongo_total for {key}: {mongo_totals[key]} exceeds request_totals for {key}: {request_totals[key]}')
    
    return outdated

test(request_totals, mongo_totals)

It seems like a lot to do my comparison before creating an object that manages updates. Is there a better way to do this?

Asked By: MrChadMWood

||

Answers:

You could try the collections Counter – it’s very efficient and clear. Note – it’s a new feature available in Python 3.10.

It’s dict subclass for counting hashable objects


from collections import Counter
cd1 = Counter(test_dict)
cd2 = Counter(test_dict2)
print(cd1 <= cd2)
# True
#
# another example:
cd3 = Counter({'a': 2, 'b': 2, 'c': 3})
print(cd3 <= cd2)
#False
print(cd2 <= cd3)
#True
Answered By: Daniel Hao
all(test_dict2.get(k, v-1) >= v
    for k, v in test_dict.items())

Try it online!

Answered By: Kelly Bundy
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.