Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python dictionary ordering with equal keys

I thought this must already have been answered, but I couldn't find anything on Google or here.

I'm aware that, in general, you cannot rely on the ordering of a Python dictionary. However, if you have two dictionaries with identical keys, can you rely on the values being in the same order as well?

I ask because I'm trying to compare two dictionaries of floating point numbers, so I cannot use dict1==dict2. My function looks something like this:

def _compare_dict(self, d1, d2):
    """
    Compares two dictionaries of floating point numbers
    for equality.
    """
    if d1.keys() != d2.keys():
        return False

    zipped = zip(d1.itervalues(), d2.itervalues())
    return len(filter(lambda x: abs(x[0] - x[1]) > sys.float_info.epsilon, zipped)) == 0

Is this a dangerous game to play? In one test, the order seemed to hold:

In [126]: d1={'a': 3, 'b': 2, 'c': 10}
In [127]: d2={'b': 10, 'c': 7, 'a': 2}

In [128]: d1
Out[128]: {'a': 3, 'b': 2, 'c': 10}

In [129]: d2
Out[129]: {'a': 2, 'b': 10, 'c': 7}

But I don't know if this is something I can count on. Other solutions for comparing two dictionaries of floating point numbers are welcome too, of course.

like image 744
Taj Morton Avatar asked Feb 12 '26 05:02

Taj Morton


1 Answers

Depending on how the dictionaries were built, you can't rely on that.

some example:

>>> a = dict.fromkeys(range(1000))
>>> b = dict.fromkeys(range(500,600))
>>> for i in range(500):
    del a[i]

>>> for i in range(600,1000):
    del a[i]

>>> all(i==j for i,j in zip(a,b))
False
>>> a == b
True

a is a much bigger hash table because it has allocated space for 1000 objects while b can only hold about 100 without growing a little. So the way the hashes are stored can change the iteration order

like image 69
JBernardo Avatar answered Feb 14 '26 19:02

JBernardo