pythondictionaryiterator

Python equivalent of zip for dictionaries


If I have these two lists:

la = [1, 2, 3]
lb = [4, 5, 6]

I can iterate over them as follows:

for i in range(min(len(la), len(lb))):
    print la[i], lb[i]

Or more pythonically

for a, b in zip(la, lb):
    print a, b

What if I have two dictionaries?

da = {'a': 1, 'b': 2, 'c': 3}
db = {'a': 4, 'b': 5, 'c': 6}

Again, I can iterate manually:

for key in set(da.keys()) & set(db.keys()):
    print key, da[key], db[key]

Is there some builtin method that allows me to iterate as follows?

for key, value_a, value_b in common_entries(da, db):
    print key, value_a, value_b 

Solution

  • There is no built-in function or method that can do this. However, you could easily define your own.

    def common_entries(*dcts):
        if not dcts:
            return
        for i in set(dcts[0]).intersection(*dcts[1:]):
            yield (i,) + tuple(d[i] for d in dcts)
    

    This builds on the "manual method" you provide, but, like zip, can be used for any number of dictionaries.

    >>> da = {'a': 1, 'b': 2, 'c': 3}
    >>> db = {'a': 4, 'b': 5, 'c': 6}
    >>> list(common_entries(da, db))
    [('c', 3, 6), ('b', 2, 5), ('a', 1, 4)]
    

    When only one dictionary is provided as an argument, it essentially returns dct.items().

    >>> list(common_entries(da))
    [('c', 3), ('b', 2), ('a', 1)]
    

    With no dictionaries, it returns an empty generator (just like zip())

    >>> list(common_entries())
    []