Python:从理解中删除空列表

时间:2013-08-09 22:22:44

标签: python list-comprehension

我正在实现dijkstras算法来计算最短路径。我的问题是,是否有更简洁的方法来实现以下理解(即没有if [b for a,b in G[x] if a not in X]!=[]]加到最后)。

在下文中,G是一个图表,其中的键是图形节点,每个节点都有一个表示其连接边缘的元组列表。因此每个元组包含以下信息:(连接节点,到连接节点的距离)。 X是算法已经查看过的一组节点,A是将已经找到的节点映射到起始节点的最短距离,在这种情况下是节点1.

更新:抱歉,我举了一个有效的例子,如果删除了理解的最后部分,这里就不起作用。

G = {1: [(2, 20), (3, 50)], 2: [(3, 10), (1, 32)], 3: [(2, 30), (4, 10)], 4: [(1, 60)]}
X = {1,2,3}
A = {1: 0, 2: 20, 3:30}

mindist = min([A[x] + min([b for a,b in G[x] if a not in X]) for x in X if [b for a,b in G[x] if a not in X]!=[]])

问题是如何将思维导师写成可以处理min([[],[some number],[])的理解。

最后一部分, if [b for a,b in G[x] if a not in X]!=[]] 只是删除空列表,所以min不会失败,但是有更好的方法来编写它 理解所以没有空列表。

4 个答案:

答案 0 :(得分:2)

这是一个想法:

minval = [float('+inf')]
min(A[x] + min([b for a, b in G[x] if a not in X] + minval) for x in X)
=> 40

诀窍?确保最里面的min()总是有一个值可以使用,即使它是一个虚拟的:一个正的无限,因为任何东西都会比它小。通过这种方式,最外面的min()将在计算最小值时忽略inf值(对应于空列表)。

答案 1 :(得分:1)

首先,空列表在布尔值中被视为false,因此您无需针对[]测试不等式; if [b for a,b in G[x] if a not in X]就足够了。

你真正想做的是生成内部列表一次,然后一次性测试和计算最小值。使用额外的内部'循环'来做到这一点:

mindist = min(A[x] + min(inner) 
              for x in X 
              for inner in ([b for a,b in G[x] if a not in X],) if inner)

for inner over (...,)循环迭代生成列表一次的单元素元组,以便在计算之前可以测试它是否为空(if inner)将A[x] + min(inner)结果传递给外部 min()来电。

请注意,您不需要该外循环的列表推导;这是一个生成器表达式,可以节省您构建列表对象,然后再次将其丢弃。

演示:

>>> G = {1: [(2, 20), (3, 50)], 2: [(3, 10), (1, 32)], 3: [(2, 30), (4, 10)], 4: [(1, 60)]}
>>> X = {1,2,3}
>>> A = {1: 0, 2: 20, 3:30}
>>> min(A[x] + min(inner) 
...               for x in X 
...               for inner in ([b for a,b in G[x] if a not in X],) if inner)
40

答案 2 :(得分:1)

好的,我必须解开那个坚果列表理解来弄清楚你在说什么 - 我认为这是大致相同的代码:

dists = []
for x in X:
    newdists = [b for a,b in G[x] if a not in X]
    if len(newdists) > 0
        dists.append(A[x] + min(newdists))
mindist = min(dists)

这是一种消除相关测试的方法:

import sys

def newMin(values):
    if len(values) == 0:
        return float('inf')
    else:
        return min(values)

mindist = min(A[x] + newMin([b for a,b in G[x] if a not in X]) for x in X)

print mindist

输出:

40

答案 3 :(得分:0)

这不是一个完整的解决方案,但由于你刚刚摆脱空列表,你可以缩短条件。空列表被评估为False。包含任何内容的列表将被评估为true。只需提供列表作为条件。对于所有空的内置数据类型都是如此。