pythonlist-comprehensiongeneratorgurobi

How to get the index of function parameter list comprehension


Gurobipy can apparently read the index of a list comprehension formulated within the parentheses of a function. How does this work? Shouldn't this formulation pass a generator object to the function? How do you read the index from that?

    md = gp.Model()
    md.addConstrs(True for i in [1,2,5,3])
    

The output contains the indices that where used in the list comprehension formulation:

{1: <gurobi.Constr *Awaiting Model Update*>,
 2: <gurobi.Constr *Awaiting Model Update*>,
 5: <gurobi.Constr *Awaiting Model Update*>,
 3: <gurobi.Constr *Awaiting Model Update*>}

Solution

  • I am not sure if I understand your question correctly, but if you are wondering how you can retrieve the iterator from generator expression, then that's by accessing <generator>.gi_frame.f_locals.

    The gi_frame contains the frame object corresponds to the generator expression and it has f_locals attribute which denotes the local namespace seen by this frame.

    >>> my_gen = (True for i in [1,2,5,3])
    >>> type(my_gen)
    <class 'generator'>
    >>> my_gen.gi_frame.f_locals
    {'.0': <tuple_iterator object at 0x1003cfa60>}
    >>> my_gen.gi_frame.f_locals['.0']
    <tuple_iterator object at 0x1003cfa60>
    >>> list(my_gen.gi_frame.f_locals['.0'])
    [1, 2, 5, 3]
    

    You can even use the more direct API inspect.getgeneratorlocals.

    >>> import inspect
    >>> 
    >>> inspect.getgeneratorlocals(my_gen)
    {'.0': <tuple_iterator object at 0x1003cfc70>}
    

    But please do note that:

    CPython implementation detail: This function relies on the generator exposing a Python stack frame for introspection, which isn’t guaranteed to be the case in all implementations of Python. In such cases, this function will always return an empty dictionary.