簡體   English   中英

Python:從理解范圍內刪除空列表

[英]Python: remove empty lists from within comprehension

我正在實現dijkstras算法來計算最短路徑。 我的問題是,是否有一種更干凈的方法來實現下面的理解(即if [b for a,b in G[x] if a not in X]!=[]]沒有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不會失敗,但是有一種更好的方式來編寫該理解,因此沒有空列表。

這是一個主意:

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值(對應於空列表)。

首先,空列表在布爾值中被認為是假的,因此您不需要針對[]檢驗不等式。 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 (...,)循環遍歷一次生成列表的單元素元組,因此您可以在計算A[x] + min(inner) )之前測試它是否為空( 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

好的,我必須解開堅果列表的理解,才能弄清楚您在說什么-我認為這與大約相同的代碼:

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

這不是一個完整的解決方案,但是由於您只是擺脫了空列表,因此可以縮短條件。 空列表被評估為False。 其中包含任何內容的列表被評估為true。 只需提供列表作為條件即可。 對於所有空的內置數據類型都是如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM