CoconutBandit CoconutBandit - 2 months ago 9
Python Question

Type of variable changes based on access?

I have a directed graph structure consisting of nodes and edges both of which subclass an Event parent class. Depending on external events, edges can either be active or inactive. I then find all the directed paths from a given node to the root node, but I really only care about the nodes along the way, not the edges. For instance, to convert from a set of edges to a set of nodes I use:

>>> paths
[[<Edge F>, <Edge B>]]
>>> lst = [set(map(lambda e: e.tail, path)) for path in paths]


where path is a list of edges. This is what confuses me: when I go to check the contents of
lst
, it changes depending on how I access it

>>> lst
[set([<Node 2>, <Node 1>])]
>>> [type(n) for n in path for path in lst]
[<class 'libs.network.Edge'>, <class 'libs.network.Edge'>]
>>> [type(n) for n in lst[0]]
[<class 'libs.network.Node'>, <class 'libs.network.Node'>]


Why aren't these two ways of accessing the type information the same?

Answer

You have your list comprehension order wrong. Nested loops are listed from left to right.

So the expression

[type(n) for n in path for path in lst]

is executed as

for n in path:
    for path in lst:
        type(n)

so n is taken from some random pre-assigned path variable you had before, and it is that variable that contains Edge instances. Those objects have nothing to do with the contents of lst[0] you loop over in your other expression.

You probably wanted to do this the other way around:

[type(n) for path in lst for n in path]

so that path is actually set from lst before you iterate over it.