dict comparison [was: suggestions, comments on an "is_subdict" test]

Peter Otten __peter__ at web.de
Fri Apr 22 21:28:04 CEST 2011


Zero Piraeus wrote:

> :
> 
> On 22 April 2011 13:30, Peter Otten <__peter__ at web.de> wrote:
>>>>> def is_subdict(test_dct, base_dct):
>> ...     return test_dct <= base_dct and all(test_dct[k] == base_dct[k]
>> for ... k in test_dct)
>> ...
>>>>> is_subdict({1:0}, {2:0})
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in <module>
>> File "<stdin>", line 3, in is_subdict
>> File "<stdin>", line 3, in <genexpr>
>> KeyError: 1
>>
>> I think you have to convert to sets before performing the <= comparison
>> to get a proper subset test.
> 
> Huh. I thought I remembered that dict comparison worked like set
> comparison (and my admittedly minimal testing seemed to confirm that).
> Turns out it's actually "consistent, but not otherwise defined" beyond
> equality.
> 
>   http://docs.python.org/reference/expressions.html#id15
> 
> I maintain that the behaviour I expected makes more sense ;-) 
> I wonder
> whether making it work the way I want it to (dammit) would have been
> as prohibitively expensive as the lexicographical comparison mentioned
> in the footnote referenced in the above link?

The discussion is moot for Python 2, and because of backwards compatibility 
has been for a long time. Python 3 uses a different approach:

>>> {1:0} < {1:0}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: dict() < dict()

This is the behaviour that makes the most sense to me. I would have 
preferred attempts at set comparison to raise the same error which would 
have prevented surprises like

>>> a, b = {1}, {2}
>>> a < b, a > b, a == b
(False, False, False)
>>> a, b = sorted([{1}, {2}])
>>> a <= b
False





More information about the Python-list mailing list