for 循环中对全局变量属性的赋值在循环范围之外不可用

问题描述 投票:0回答:1

这是这个SO问题(link)的简化版本,带有一些程序输出。

在 macOS 下使用 Python 和 networkX,我无法为边缘属性分配值,如下所示:

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.")

这是输出:

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.

那么,如何从 for 循环内部修改边缘属性并使更改在循环范围之外持续存在?

我如何访问此作业的结果:

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

在 for 循环之外?

这感觉像是某种范围错误,但我承认我对 Python 和 networkX 都很陌生。我想知道我是否应该以某种方式将 G 传递到 for 循环中,但我不知所措。

python networkx
1个回答
0
投票

答案也在评论里。 感谢:
https://stackoverflow.com/users/1766544/kenny-ostrom
https://stackoverflow.com/users/218663/jonsg

...寻求帮助。

这是我误解 Python 生成器工作原理的一个例子。切换到:

G[行['城市1']][行['城市2']]['shortPaths'] =列表(shortPaths)

效果很好。

我认为有趣的是,我对生成器的误解和学习的这个例子似乎模仿了范围违规。 对于其他发现自己以类似方式挣扎的人来说,这可能是一个提示。

© www.soinside.com 2019 - 2024. All rights reserved.