Convert a dictionary of iterables into an iterator of dictionaries
Interesting question.

I decided to look only at itertools.product(*map(pair_iter_safe, &lt;the_dict&gt;.items())) and pair_iter_safe.

The way I look at it is from a theoretic memory usage perspective. Due to how you have defined it, all (key, value) pairs need to be in memory at the same time, which could take a bit of memory.

I would suggest the following:

def iter_safe(value):
    if isinstance(value, str):
        value = (value,)
    try:
        iter(value)
    except TypeError:
        return (value,)
    else:
        return value


And using it as follows:

def dict_combinations(d):
    keys, values_list = zip(*d.items())
    for values in itertools.product(*map(iter_safe, values_list)):
        yield dict(zip(keys, values))


To me this is cleaner, having separated out the iter_safe logic from the dicts.

Though merely theoretical, I think this should save on memory usage due to there not being as much key-value pairs in memory all the time.

Of course, if you still want pair_iter_safe, you should be able to do something like

def pair_iter_safe(kv_pair):
    key, value = kv_pair
    for v in iter_safe(value):
        yield key, v