2012-06-19 2 views
0

리스트 L의 각 요소는 필드 (필드, 크기)의 튜플입니다. 예를파이썬에서 가장 교차하지 않는 멤버를 찾는 컬리스트 목록

L = [ (['A','B'], 5), (['A'], 6), ('C', 1)] 

위해 나는 단지 교차하지 않는 구성원이 포함되도록 목록을 추려 싶습니다, 그리고 남아있는 각 구성원은 교차 할 수있는 어떤 다른 회원보다 큰.

def betterItem(x, y): 
    return (x != y and 
      set(x[0]) & set(y[0]) and 
      x[1] > y[1]) 

for i in range(len(L)-1): 
    L[:] = [x for x in L for y in L if betterItem(x, y)] 

이 일을 더 나은/빠른/더 파이썬 방법이 있나요 : 그래서 예를 들어리스트 L은 현재 내가 그렇게처럼 구현 한

L = [ (['A'], 6), ('C', 1)] 

로 감소 될 것이다?

도움 주셔서 감사합니다.

[(['A'], 6), (['C'], 1)] 

에서

+0

나에게 상당히 비현실적 인 것처럼 보입니다. 네가 그곳에서 너무 느린가? 목록 구성원간에 일치하는 인덱스 쌍을 찾은 다음 해당 인덱스에서 betterItem 만 호출하여 인덱스 구성원을 줄이기 위해 시도해 볼 수 있습니다. –

+0

@Lattyware 완료, 알림을 주셔서 감사합니다 ... 내 SO 방문은 매우 가끔 경향이 있으며 그렇게하는 것을 잊어 버립니다. – Albeit

답변

1
L = [(['A','B'], 5), (['A'], 6), (['C'], 1)] 

# sort by descending value 
L.sort(key=lambda s:s[1], reverse=True) 

# keep track of what members have already occurred 
seen = set() 

# Cull L - ignore members already in `seen` 
# (Because it is presorted, already-seen members must have had a higher value) 
L = [seen.update(i) or (i,j) for i,j in L if seen.isdisjoint(i)] 

결과는 (이 지능형리스트의 비트를 사용 재빠른 손재주 : seen.update 항상 None을 반환하고 None or x 항상 x 반환 - 그래서 seen.update(i) or (i,j) 반환 튜플 (i,j)을면 - 본 회원 목록 업데이트의 영향)

O (n^2) 대신 sort으로 인해 O (n log n)이어야합니다.

+0

이것은 내가 찾고있는 것일 뿐이지 만, 속도 향상을 위해 너무 복잡하다. (이를 수행하기 위해 엄청난 목록을 가지지 않을 것이다.) 감사. – Albeit