[Python] Assignment to global variable attribute in for loop is not available outside the...

Discussão em 'Python' iniciado por Stack, Dezembro 18, 2024.

  1. Stack

    Stack Membro Participativo

    This is a simplified version of this SO question (link) with some program output.

    Using Python and networkX under macOS, I am not able to assign a value to an edge attribute as follows:

    import networkx as nx
    import matplotlib.pyplot as plt
    import pandas as pd
    import matplotlib.pyplot as plt
    from pyvis.network import Network
    from io import StringIO

    csv_cities= """City,Location,Lon,Lat,x,y,,LonDat,LatDat
    Los Angeles,"Los Angeles, California, United States",-118.254190,34.048050,140,328,q,-123.114980,25.761681
    New York,"New York, New York, United States",-74.005994,40.712749,1415,591,q,-71.056800,51.045700
    Atlanta,"Atlanta, Georgia, United States",-84.389854,33.750800,1116,316,q,-94.971032,39.002842
    Chicago,"Chicago, Illinois, United States",-87.632360,41.881954,1022,638,q,52.05818,25.284019 """

    csv_connections= """City1,City2,numTracks,NumCarSpots,Colors,SegmentTotalCarSpots
    Chicago,Los Angeles,1,4,Blue,4
    New York,Chicago,2,2,"Orange, Black",4
    Atlanta,Chicago,1,3,Blue,3"""

    cities = pd.read_csv(StringIO(csv_cities))
    interCityConnections = pd.read_csv(StringIO(csv_connections))

    G = nx.Graph()

    #Add cities to graph
    coords={}
    for index, row in cities.iterrows():
    print(f"{row['City']:<17} {int(row['x']):<6} {int(row['y']):<6}")
    G.add_node(row['City'],city=True, x=row['x'], y=row['y'], physics=False,
    label=row['City'], title=f'{row['x']},{row['y']}')
    coords[row['City']]=int(row['x']),int(row['y'])

    print("- 1 - ")

    #Add intercity connections
    for index, row in interCityConnections.iterrows():
    print(f"{row['City1']:>17} <-{row['NumCarSpots']} {row['Colors']}-> {row['City2']:<17} ")
    G.add_edge(row['City1'],row['City2'],interCity=True,numTracks=row['numTracks'])
    G[row['City1']][row['City2']]['taxes']="Major" # This works
    shortPaths=nx.all_shortest_paths(G,row['City1'], row['City2'])
    G[row['City1']][row['City2']]['shortPaths']=shortPaths #some assignment happens here
    # but value not usable outside loop?
    for p in shortPaths: #This works
    print(f"Path:{p}") #This works

    print("- 2 - ")

    print(G['Atlanta']['Chicago'])
    print(f"type:{type(G['Atlanta']['Chicago']['shortPaths'])}")
    for p in G['Atlanta']['Chicago']['shortPaths']:
    print("For looping...") # This never executes
    print(f"Path:{p}") # This never executes
    print("Done. There should be a path displayed above this line.")


    This is the output:

    q@q-mbp ttr % py simplebug.py
    Los Angeles 140 328
    New York 1415 591
    Atlanta 1116 316
    Chicago 1022 638
    - 1 -
    Chicago <-4 Blue-> Los Angeles
    Path:['Chicago', 'Los Angeles']
    New York <-2 Orange, Black-> Chicago
    Path:['New York', 'Chicago']
    Atlanta <-3 Blue-> Chicago
    Path:['Atlanta', 'Chicago']
    - 2 -
    {'interCity': True, 'numTracks': 1, 'taxes': 'Major', 'shortPaths': <generator object _build_paths_from_predecessors at 0x10d107480>}
    type:<class 'generator'>
    Done. There should be a path displayed above this line.


    So, how can I modify an edge attribute from inside that for loop and have the change persist outside the scope of the loop?

    How can I access the result of this assignment:

    G[row['City1']][row['City2']]['shortPaths']=shortPaths


    outside the for loop?

    This feels like some kind of scope bug, but I admittedly am quite new to both Python and networkX. I wonder if I should be passing G into the for loop somehow, but I am at a loss.

    Continue reading...

Compartilhe esta Página