Test if dict contained in dict

后端 未结 4 1256
一向
一向 2020-12-24 11:19

Testing for equality works fine like this for python dicts:

first  = {\"one\":\"un\", \"two\":\"deux\", \"three\":\"trois\"}
second = {\"one\":\"un\", \"two\         


        
4条回答
  •  不思量自难忘°
    2020-12-24 12:13

    You can use a dictionary view:

    # Python 2
    if first.viewitems() <= second.viewitems():
        # true only if `first` is a subset of `second`
    
    # Python 3
    if first.items() <= second.items():
        # true only if `first` is a subset of `second`
    

    Dictionary views are the standard in Python 3, in Python 2 you need to prefix the standard methods with view. They act like sets, and <= tests if one of those is a subset of (or is equal to) another.

    Demo in Python 3:

    >>> first  = {"one":"un", "two":"deux", "three":"trois"}
    >>> second = {"one":"un", "two":"deux", "three":"trois", "foo":"bar"}
    >>> first.items() <= second.items()
    True
    >>> first['four'] =  'quatre'
    >>> first.items() <= second.items()
    False
    

    This works for non-hashable values too, as the keys make the key-value pairs unique already. The documentation is a little confusing on this point, but even with mutable values (say, lists) this works:

    >>> first_mutable = {'one': ['un', 'een', 'einz'], 'two': ['deux', 'twee', 'zwei']}
    >>> second_mutable = {'one': ['un', 'een', 'einz'], 'two': ['deux', 'twee', 'zwei'], 'three': ['trois', 'drie', 'drei']}
    >>> first_mutable.items() <= second_mutable.items()
    True
    >>> first_mutable['one'].append('ichi')
    >>> first_mutable.items() <= second_mutable.items()
    False
    

    You could also use the all() function with a generator expression; use object() as a sentinel to detect missing values concisely:

    sentinel = object()
    if all(first[key] == second.get(key, sentinel) for key in first):
        # true only if `first` is a subset of `second`
    

    but this isn't as readable and expressive as using dictionary views.

提交回复
热议问题