2013-08-09 2 views
2

나는 최단 경로를 계산하기 위해 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]!=[]] 그냥 빈 목록을 제거하지만 거기는 빈리스트가 없기 때문에 그 이해를 작성하는 더 좋은 방법입니다.

+0

빈 목록은 False로 평가됩니다. –

답변

2

23,516,는 생각? 가장 안쪽에있는 min()이 더미 인 경우에도 항상 작동 할 값이 있는지 확인하십시오. 양의 값은 무한합니다. 왜냐하면 아무 것도 작을 것이기 때문입니다. 이런 식으로 가장 바깥 쪽 min()은 최소값을 계산할 때 inf 값 (빈 목록에 해당)을 무시합니다.

+1

단순함을 위해이 대답과 함께 진행합니다 :) – jenesaisquoi

0

완전한 해결책은 아니지만 빈 목록을 없애고 있기 때문에 조건을 줄일 수 있습니다. 빈 목록은 False로 평가됩니다. 목록에있는 내용이 모두 참으로 평가됩니다. 목록을 조건으로 제공하기 만하면됩니다. 이는 모든 비어있는 내장 데이터 유형에 해당됩니다.

1

우선 빈 목록은 부울로 간주되므로 불평등을 []에 대해 테스트 할 필요가 없습니다. 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() 호출로 전달할 수 있습니다.

해당 외부 루프에는 목록 이해가 필요하지 않습니다. 이것은 생성자 표현식 대신, 당신이 다시 버려지는 목록 객체를 저장하는 것을 의미합니다.여기의

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) 

: - :

데모 나는이 거의 같은 코드라고 생각

>>> 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 
+0

흥미 롭기 때문에 [if inner]는 []를 제거하는 데 필요한 모든 것입니까? 나는 발전기가 어떻게 작동하는지 이해하지 못한다고 생각한다. – jenesaisquoi

+0

@noah : 빈 목록은 불리언 문맥에서 거짓입니다. '! = []'은 생성자 표현식뿐만 아니라 어디서든 중복됩니다. –

1

좋아, 난 당신에 대해 얘기했다 알아낼 그 열매 지능형리스트를 압축했다

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 

출력 :

01 문제의 시험을 제거 방법

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 

트릭 : 여기

40 
+0

계산 된 경로의 길이가 sys.maxint보다 큰 경우 알고리즘이 실패 할 수 있으므로 최상의 솔루션이 아닐 수 있습니다. – Brionius

+0

'min (A [x] + min (X에 X가 없으면 G [x]에있는 b, [float ('inf')]에 해당)) : – GP89

+0

좋은 아이디어 - 나는 그것을 sys.maxint 자리에 통합 할 것이다. – Brionius

관련 문제