Home > Software engineering >  how to compare values of two dictionaries with list comprohension?
how to compare values of two dictionaries with list comprohension?

Time:11-28

How to compare only the values of two dictonaries?

So I have this:

dict1 = {"appe": 3962.00, "waspeen": 3304.08}
dic2 = {"appel": 3962.00, "waspeen": 3304.08}


def compare_value_dict(dic):
    return dic

def compare_value_dict2(dic2):   
    return dic2
    

def compare_dic(dic1, dic2):
    if dic1 == dic2:       
        print('the same dictionary')
    else:      
        print('difference dictionary')

compare_dic(compare_value_dict(dict1).values(), compare_value_dict2(dic2.values()))

but I get the print statement:

 print('difference dictionary')

But the values are the same. And can this be shorter with list comprohension?

this works:

compare_dic(compare_value_dict(dict1).keys(), compare_value_dict2(dic2.keys()))

if I change only the key then it outputs the difference.

But with values. it doesn't work. if the values are the same, but the keys are different, that it returns difference. But it has to be of course not difference

CodePudding user response:

You can't use == on the dict.values() dictionary view objects, as that specific type doesn't act like a set. Instead values_view_foo == values_view_bar is only ever true if both refer to the same dictionary view object. The contents don't matter.

It'll depend entirely on the types of values that the dictionary contains on what techniques can be used here. The following options will cover many different types of values, but not all. It is not really possible to make a generic one-size-fits-all comparison function for all possible types of values in a dictionary.

In this specific case, you can turn your values views into sets, because the values happen to both be unique and hashable:

def compare_dict_values(dv1, dv2):
    """Compare two dictionary values views

    Values are assumed to be unique and hashable

    """
    return set(dv1) == set(dv2)

Where the values are not unique, and / or not hashable, you'll have to find another way to compare the values.

If they are, say, sortable (orderable), then you could compare them by first sorting the values:

def compare_dict_values(dv1, dv2):
    """Compare two dictionary value views

    Values are assumed to be orderable, but do not need to be unique
    or hashable.

    """
    return len(dv1) == len(dv2) and sorted(dv1) == sorted(dv2)

By sorting you remove the issue with the values view being unordered. The len() check is there because it is much cheaper than sorting and so let’s you avoid the sort when it is not necessary.

If the values are hashable but not unique (and so the values collection ('foo', 'bar', 'foo') is different from ('foo', 'bar', 'bar')), you can use Counter() objects to capture both the values and their counts:

from collections import Counter

def compare_dict_values(dv1, dv2):
    """Compare two dictionary value views

    Values are assumed to be hashable, but do not need to be unique.

    """
    return Counter(dv1) == Counter(dv2)

Note: Each of these techniques assume that the individual values in the dictionary support equality testing and you only need them to be exactly equal. For floating point values, you can run into issues where the values are almost equal, but not exactly equal. If your values need to be close and not just exactly equal, you can use the math.isclose() function on each pair of values. Use zip(sorted(dv1), sorted(dv2)) to pair up the values:

def float_dict_values_close(dv1, dv2, **kwargs):
    """Compare two dictionary view objects with floats

    Returns true if the values in both dictionary views are
    *close* in value.

    """
    if len(dv1) != len(dv2):
        return False
    v1, v2 = sorted(dv1), sorted(dv2)
    return all(is_close(*vs, **kwargs) for vs in zip(v1, v2))

Things get more complicated if your values can be different types; you generally can't sort a dictionary values view with a mix of different types in it. If you have a mix of types where not all the types are hashable, you'd have to separate out the different types first and then use a mixture of techniques to compare the values of the same type. This gets complicated when you have a hierarchy of types where subclasses can be compared with superclasses, etc. I'm declaring that as outside the scope of this answer.

CodePudding user response:

so you wanna check if your dictionaries are same with their values right?

dict1 = {"appe": 3962.00, "waspeen": 3304.08}
dic2 = {"appel": 3304.08, "waspeen": 3962.00}
def comparision(*dicts):
    instanceToCompare , values = len(dicts[0].values()) , set()
    for d in dicts:
        for value in d.values():
            values.add(value)
    return True if len(values) == instanceToCompare else False
print('all dictionaries has same values') if comparision(dict1 , dic2) else 
print('input dictionaries are not same at all')

you'll know if all values in dictionaries are same or not , regardless to their order or repitation

CodePudding user response:

you can go with the function dic.keys() that returns a vector containing all "headers" from your dictionary. And in the for loop, you can compare.

  • Related