【问题标题】:How to access an element from a list of lists in python networkX? TypeError: 'int' object is not iterable如何从 python networkX 中的列表列表中访问元素? TypeError:“int”对象不可迭代
【发布时间】:2021-04-17 23:21:42
【问题描述】:

我的循环有一个输出,其中 G 是来自 networkX 的图表。

for node in G.nodes():
    start_end = [(node,k) for k,v in nx.shortest_path_length(G, node).items() if v == d]
    print (start_end)

里面有很多包含元组的列表类。 (如果只是一个列表,那么 start_end[0][0] 很容易。)

<class 'list'>
<class 'list'>
<class 'list'>
<class 'list'>
....
[]
[]
[]
[]
[]
[]
[('45', '27'), ('45', '26'), ('45', '39'), ('45', '24'), ('45', '81'), ('45', '29'), ('45', '46'), ('45', '51'), ('45', '23'), ('45', '8'), ('45', '60'), ('45', '83'), ('45', '86'), ('45', '149'), ('45', '18'),  ('45', '99'), ('45', '78'), ('45', '120'), ('45', '134'), ('45', '121'), ('45', '122')]
[]
[]
[]
[]
[]
[]
[('129', '134')]
[]
[('134', '92'), ('134', '97')]
[]
[]
[]
[]
[]

在本例中,我想获取最长列表 '45' 的第一个元素。 我尝试按长度对列表进行排序。

sorted(start_end, reverse=True)
max(start_end)

产生错误

#TypeError: 'int' object is not iterable

我也试过

start_end = len([(node,k) for k,v in nx.shortest_path_length(G_sc, node).items() if v == d])
print(max(current))

同样的错误。

以下是您可以重现的伪代码。 在这里,如何从第二个(最长的)列表中访问元组 ((2, 1)?

In: 
import networkx as nx
G = nx.DiGraph()

G.add_edge(1,2); G.add_edge(1,4)
G.add_edge(3,1); G.add_edge(3,4)
G.add_edge(2,3); G.add_edge(4,3)

for node in G.nodes():
    start_end_nodes = [(node, k) for k,v in nx.shortest_path_length(G, 
                      node).items() if v == 2]
    
    print(start_end_nodes)

Out:
[(1, 3)]
[(2, 1), (2, 4)]
[(4, 1)]
[(3, 2)]

【问题讨论】:

  • 您可能想检查nx.shortest_path_length(G, node) 及其items() 返回的内容。
  • dict_items([元组,元组,元组..])? TypeError: 'dict_items' 对象不可下标
  • 这看起来像是一个按长度排序的问题,不是吗?

标签: python list loops list-comprehension networkx


【解决方案1】:

解决此问题的一种方法是将所有 start_end 值存储在一个列表中 - start_ends - 然后根据 len 获取最大值:

max(start_ends, key=len)

完整代码

def f2(G):
    start_ends = []
    d = 2
    for node in G.nodes():
        start_end = [(node, k) for k,v in nx.shortest_path_length(G, node).items() if v == d]
        start_ends.append(start_end)
        
    #print(max(start_ends, key=len)[0])
    return max(start_ends, key=len)[0]

对于您的图表:

#In:
G = nx.DiGraph()

G.add_edge(1,2); G.add_edge(1,4)
G.add_edge(3,1); G.add_edge(3,4)
G.add_edge(2,3); G.add_edge(4,3)

f2(G)

#Out:
(2, 1)

选项 2:

您也可以使用sorted 来获得相同的效果,但如果您希望列表排序而不仅仅是最大值,我建议您使用它。

# to sort use:
start_ends_sorted = sorted(start_ends, key=len, reverse=True)

# to get the same result as before:
start_ends_max = start_ends_sorted[0][0]

# ---------------
# In your example:
start_ends_sorted = [[(2, 1), (2, 4)],
                     [(1, 3)],
                     [(4, 1)],
                     [(3, 2)]]
start_ends_max = (2, 1)

【讨论】:

  • 谢谢你,willcrack。有人对我的问题投了反对票,但我只是在 coursera 课程上学习这个。我在这里提问是因为不允许学生在他们的论坛上发布任何代码解决方案!
  • 是的,我会将其标记为已接受的答案:)
【解决方案2】:

有人通过创建一个空字典向我推荐了这个版本。 所以我试图了解它是如何工作的,更具体地说,'scores[node] = end_node 行,以及它是否比你的更好(更快)。

def f2(G):        
    scores = {}
    d = 2
            
    for node in G.nodes():
        shortest = nx.shortest_path_length(G_sc, node)
        end_node = len([k for k,v in shortest.items() if v == d])
        scores[node] = end_node
    return ((max(scores))

【讨论】:

  • 好吧,不幸的是,这个解决方案将返回4 而不是(2,1),因为4最高节点标签。如果您想获得start_node 标签(2),请将return ((max(scores)) 更改为return max(scores, key=lambda k: scores[k])。此解决方案似乎稍快一些:[在 7 次运行中:1.04 s vs. 1.06 s 用于 1000 节点 Barabasi-Albert 图]
猜你喜欢
  • 2019-07-24
  • 2022-01-20
  • 2023-03-07
  • 2014-02-08
  • 2015-10-23
  • 1970-01-01
  • 2019-12-03
  • 1970-01-01
  • 2015-04-06
相关资源
最近更新 更多