Test script for pairs:: >>> from bidict import pairs Abstracts differences between Python 2 and 3:: >>> it = pairs({1: 2}) >>> next(it) (1, 2) >>> next(it) Traceback (most recent call last): ... StopIteration Accepts zero or one positional argument which it first tries iterating over as a mapping (as above), and if that fails, falls back to iterating over as a sequence, yielding items two at a time:: >>> it = pairs([(1, 2), (3, 4)]) >>> next(it) (1, 2) >>> next(it) (3, 4) >>> next(it) Traceback (most recent call last): ... StopIteration >>> list(pairs()) [] Mappings may also be passed as keyword arguments, which will be yielded after any passed via positional argument:: >>> list(sorted(pairs(a=1, b=2))) [('a', 1), ('b', 2)] >>> list(sorted(pairs({'a': 1}, b=2, c=3))) [('a', 1), ('b', 2), ('c', 3)] >>> list(sorted(pairs([('a', 1)], b=2, c=3))) [('a', 1), ('b', 2), ('c', 3)] In other words, this is like a generator analog of the dict constructor. If any mappings from a sequence or keyword argument repeat an earlier mapping in the positional argument, repeat mappings will still be yielded, whereas with dict the last repeat clobbers earlier ones:: >>> dict([('a', 1), ('a', 2)]) {'a': 2} >>> list(pairs([('a', 1), ('a', 2)])) [('a', 1), ('a', 2)] >>> dict([('a', 1), ('a', 2)], a=3) {'a': 3} >>> list(pairs([('a', 1), ('a', 2)], a=3)) [('a', 1), ('a', 2), ('a', 3)] Invalid calls result in errors:: >>> list(pairs(1, 2)) Traceback (most recent call last): ... TypeError: Pass at most 1 positional argument (got 2)