如何将代码扁平化为列表理解?

时间:2018-01-17 16:48:17

标签: python python-3.x list-comprehension

我有这段代码:

for aaa_binary in groups(sources, a):

    if len(dodane_pary)!=count:

       g.add_nodes_from (aaa_binary)
       t1 = (aaa_binary[0],aaa_binary[1])
       t2 = (aaa_binary[1],aaa_binary[2])
       t3 = (aaa_binary[2],aaa_binary[3])                                                 

       added_now = []                      
       for edge in (t1,t2,t3):
           if not g.has_edge(*edge):
              g.add_edge(*edge)
              added_now.append(edge)

       dodane_pary.append(aaa_binary)  

       for j in range(len(dodane_pary)):
           if nx.shortest_path(g, aaa_binary[0], aaa_binary[3])!=aaa_binary or nx.shortest_path(g, dodane_pary[j][0], dodane_pary[j][3])!=dodane_pary[j]:
              for edge in added_now:
                  g.remove_edge(*edge)
              dodane_pary.remove(aaa_binary)
              break
    else: 
        break

因此,我可能无法在我的程序中使用多处理,所以我想首先测试代码的速度,然后将其作为列表展平。

如何做到最好?用碎片压扁是否更好?例如,对于for/if对?或者更大的作品?

1 个答案:

答案 0 :(得分:5)

你做不到。您不能删除已添加到列表中的元素,但这正是您的代码所做的。您还使用break,列表推导循环不支持分解。最后但并非最不重要的是,您要向多个数据结构添加数据,而列表推导构建单个列表对象

此外,当你的循环变得这么详细时,你真的不想尝试把它变成列表理解。结果代码将是一个难以理解的混乱。

无论如何,列表理解 的速度要快得多;列表推导从常规循环执行重复列表附加中删除常量时间因子,它不是魔术子弹。这是因为列表解析避免了.append属性查找和方法调用。没什么。

也就是说,您的代码看起来真的想要了解any() functiongenerator expressions,以测试您的图表更改是否仍会产生最短路径:

aaa_binary_groups = iter(groups(sources, a))

while len(dodane_pary) < count:
    aaa_binary = next(aaa_binary_groups, None)
    if aaa_binary is None:
        # no more groups to process
        break

    # add all edges to graph, then test for shortest paths
    g.add_nodes_from(aaa_binary)
    new_edges = [edge for edge in zip(aaa_binary, aaa_binary[1:]) 
                 if not g.has_edge(*edge)]
    g.add_edges_from(new_edges)

    if (nx.shortest_path(g, aaa_binary[0], aaa_binary[3]) != aaa_binary or
            any(nx.shortest_path(g, entry[0], entry[3]) != entry
                for entry in dodane_pary)):
        # not a shortest path for every existing entry, so remove again
        g.remove_edges_from(new_edges)
    else:
        # suitable match, retain addition to graph and track added node group
        dodane_pary.append(aaa_binary)

如果zip(aaa_binary, aaa_binary[1:])中总共有四个元素,t1 iterable会为您手动定义的t2aaa_binary等变量生成相同的边元组。

我还要研究是否必须添加节点和边缘;也许你可以避免每次想要添加新组时都必须测试到目前为止添加的每个边缘。如果您可以找到这样的更改那么,您可以考虑使用功能方法添加节点组(因为您可以直接过滤您的组而不先添加它们)。一旦你可以过滤组,然后你就可以将它们添加到图形中(带有它们的边缘),然后在一个简单的循环中。