I am receiving a generator expression as an input argument to my function, and it looks like this:
(<some calculation> for item1 in list1) # single iterator case
(<some calculation> for item1 in list1 for item2 in list2) # multiple iterator case
The function is doing some internal stuff but in the end needs to return a dictionary that looks like this:
{item1: <calculated value>, ..} # single case
{(item1, item2): <calculated value>, ..} # multiple case
This works but I'd prefer to avoid messing around with what is obviously generator expression internals. Is there a clean way of making this work? I can imagine this could break in different versions of Python.
def to_dict(gen_expr):
d = {}
for x in gen_expr:
local_vars = gen_expr.gi_frame.f_locals
key = tuple(v for k, v in local_vars.items()
if k != ".0") # ".0" points to the iterator object
if len(key) == 1:
key = key[0]
d[key] = x
return d
EDIT:
This works in the IPython console but running the same piece of code in the Anaconda prompt crashes on f_locals, which then suddenly also contains all objects from the generator code block. Because these objects are not (necessarily) hashable, it raises a TypeError on d[key] = x. So my fears about (ab)using generator internals were quickly confirmed.