这是这个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 循环中,但我不知所措。
答案也在评论里。 感谢:
https://stackoverflow.com/users/1766544/kenny-ostrom
https://stackoverflow.com/users/218663/jonsg
...寻求帮助。
这是我误解 Python 生成器工作原理的一个例子。切换到:
G[行['城市1']][行['城市2']]['shortPaths'] =列表(shortPaths)
效果很好。
我认为有趣的是,我对生成器的误解和学习的这个例子似乎模仿了范围违规。 对于其他发现自己以类似方式挣扎的人来说,这可能是一个提示。