2014-02-18 2 views
2

각각 3 개의 속성이있는 객체 목록이 있는데, 내 객체 중 겹치는 속성이 있는지 찾아 내서 겹치는 속성이있는 객체 세트로 가져 오려고합니다.반복되는 속성에서의 파이썬 일치

나를 명확히하자

class Obj(): 
    '''My example objects! they have 3 attributes.''' 
    def __init__(a, b, c): 
     self.a = a 
     self.b = b 
     self.c = c 

>>>> obj1 = Obj(a= 1, b = 2, c = 3) 
>>>> obj2 = Obj(a= 1, b = 5, c = 6) 
>>>> obj3 = Obj(a= 10, b = 12, c = 3) 
>>>> obj4 = Obj(a= 0, b = 0, c = 0) 
>>>> obj5 = Obj(a= 100, b = 5, c = 5) 
>>>> obj6 = Obj(a = -10, b = 0, c = 56) 
>>>> obj7 = Obj(a = None, b = None, c = None) 

# obj2 matches obj1 on attribute: "a" 
# obj3 matches obj1 on attribute: "c" 
# obj5 matches obj2 on attribute: "b" 

# obj6 matches obj4 on attribute: "b" 

# obj7 matches no one 

따라서 내 출력해야한다 : 나는 파이썬이 할 수있는 방법이

[[obj1, obj2, obj3, obj5], [obj4, obj6], [obj7]] 

있습니까? 또한 이와 같은 것을 검색 할 수있는 핵심어가 도움이 될 것입니다. 나는 아래의 해결책을 시도했다. 그것은 ... 해커 것 같습니다.

편집 : 제 예제와 일치하도록 숫자를 변경해야했습니다. 오타를 유감스럽게 생각합니다!

편집 : 솔루션에서 나의 현재 시도 :

adict = defaultdict(list) 
for obj in list_objects: 
    adict[obj.a].append(obj) 
    adict[obj.b].append(obj) 
    adict[obj.c].append(obj) 

그런 다음 이상 2 이상의 목록에 대한() adict.values ​​검색 다음 (어떻게 든) 목록을 결합합니다.
나는 우아한 솔루션을 원하고 있습니까?

+0

그래서 "일치"가 전이되기를 원합니다. obj2가 obj1과 일치하고 obj3이 obj2와 일치하면 obj3은 속성을 공유하지 않더라도 obj1과 일치합니까? – abarnert

+2

[Union Find] (http://en.wikipedia.org/wiki/Union_find)와 같은 소리 –

+1

'obj4'와 'obj5'가 'a'값과 일치한다는 사실을 어떻게 처리하고 싶습니까? –

답변

4

전체적인 문제는 집합의 관점에서 설명되므로 집합의 관점에서 생각해 봅시다. 먼저 영어로 의사 코드를 작성하십시오 :

Start with an empty set of equivalence sets 
For each value: 
    Find all the equivalence sets that have any value that matches our value 
    Remove those equivalent sets from the result set 
    Union those equivalence sets together and add our new value 
    Add that to the result set 

그래야합니까? 비 (파이썬에서

가 빈 세트 set(), 당신은 s.remove(v)를 호출하여 설정에서 값을 제거, 당신은 s.add(v)를 호출하여 설정에 값을 추가하고 노동 조합 세트 (파괴적) s1 |= s2, 또는를 호출하여 파괴적으로) s = set.union(s1, s2, s3, …). (* 구문과 함께 사용할 수 있습니다. 집합 집합 또는 집합 목록이있는 경우 set.union(*s)을 사용하면 모두 합집합을 얻을 수 있습니다.

따라서 "까다로운 유일한 문제는"모든 동등한 집합 찾기 우리 요소와 일치하는 모든 요소가 있습니다. " "... 우리의 가치와 일치하는 모든 가치를 가짐"은 any에 대한 호출이며 이해는 any(matches(value, element) for element in equivalenceset)입니다. 그리고 "모든 동등한 세트 찾기 ..."는 이해입니다 : {equivalenceset for equivalenceset in equivalencesets if …}.

물론 matches 함수를 작성해야하지만, 쉽게 할 수 있습니다 : x.a == y.a or x.b == y.b or x.c == y.c.

그 자체로 모든 것을 작성해야합니다.

+0

죄송합니다 for 루프에서 반복되는 내용은 무엇입니까? 모든 객체의 입력 목록? (그 말이 맞지 않니?) – user1639926

+0

@ user1639926 : 바깥 쪽 루프가 모든 개체의 입력 목록을 반복합니다.각각은 등가 집합 (하나의 집합으로 여러 동등 집합을 합치는 경우도 있음)에 넣을 수 있습니다. 한번 모두 끝내면 모든 것이 끝납니다. 독해력의 내부 루프는 단일 결과 동등성 집합 및 동등성 집합의 전체 결과 집합에 각각 반복됩니다. – abarnert

+1

@ user1639926 : 이것이 최악의 경우 O (N^2)가 될 것이라는 점을 간접적으로 지적한다면 ... 사실 그렇습니다.하지만 실제로 각 객체를 서로 다른 객체와 비교해야만 알 수 있습니다. 일치하는 경우 (이 알고리즘이 처리하는 전이와 일치한다는 것을 이미 알아 낸 경우는 제외), 나는 그 주위를 전혀 보지 못합니다. – abarnert