2013-08-22 1 views
4

두 임의의 파이썬 개체의 동등성을 확인하는 가장 좋은 방법은 무엇입니까? 어떤 종류의 객체를위한 컨테이너를 작성하고 새로운 객체가 컨테이너에 저장된 이전 객체와 같은지 알아 내야한다고 가정 해 봅시다.파이썬에서 평등을위한 모범 사례

문제는 변수가 매우 동일한 객체에 바인딩되어 있는지 확인하기 때문에 "is"를 사용할 수 없다는 것입니다 (그러나 우리는 객체의 깊은 사본을 가질 수 있습니다. 원래 의미와 같습니다) . 나는 "=="을 사용할 수 없다. 왜냐하면 이러한 객체 중 일부는 numpy 배열처럼 요소별로 똑같은 값을 반환하기 때문이다.

모든 종류의 개체의 평등을 결정하는 것이 가장 좋습니다. 예를 들어

repr(objectA)==repr(objectB) 

이면 충분합니까?

: objectA == objectB가 "[]"

건배, 로버트

편집을 평가하면 아마 실패

numpy.all(objectA==objectB) 

을 :

또는 그것이 일반적인 사용하는 것입니다 좋아, 제 3의 코멘트에 관해서, 나는 더 많이 상세하게 설명한다 "당신이"동등한 물건 "의 정의는 무엇 이냐?

강한 의미에서 저는 평등에 대한 정의가 없으며, 오히려 객체가 동등한 지 여부를 결정하게합니다. 문제는 내가 이해하는 한, 각각 eq 또는 ==에 대해 잘 합의 된 표준이 없다는 것입니다. 문은 배열이나 모든 종류의 것을 반환 할 수 있습니다.

제가 염두에두고 싶은 것은 연산자는 eq 사이에 SEQ (강한 평등)를 호출하고 "is"라고 지정할 수 있습니다. SEQ는 모든 요소가 동일하다는 것을 의미 할 수있는 numpy 배열에 대해 항상 단일 불리언 값으로 평가된다는 점에서 eq보다 우수하며 객체가 자신을 동일하다고 간주하는지 여부를 결정합니다. 그러나 SEQ는 메모리에서 뚜렷한 객체가 동일 할 수 있다는 점에서 "is"보다 열등합니다.

+0

'numpy.all ([])'은'True '입니다. –

+0

파이썬에서 "풍부한 비교"를 사용하는 데 드는 대가는 더 이상 일반 항등 연산자를 쓸 수 없다는 것입니다. –

+2

이해할 수 있는지 잘 모르겠습니다. 참조를 비교하고 싶지는 않지만 (''is ''), 당신은 깊이 비교하기를 원하지 않습니다 ("요소 - 동등"은 없습니다). "동등한 물건"에 대한 당신의 정의는 무엇입니까? – freakish

답변

2

나는 당신이이 같은 사용자 정의 재귀 평등 검사기를 쓰기 제안 :

from collections import Sequence, Mapping, Set 
import numpy as np 

def nested_equal(a, b): 
    """ 
    Compare two objects recursively by element, handling numpy objects. 

    Assumes hashable items are not mutable in a way that affects equality. 
    """ 
    # Use __class__ instead of type() to be compatible with instances of 
    # old-style classes. 
    if a.__class__ != b.__class__: 
     return False 

    # for types that implement their own custom strict equality checking 
    seq = getattr(a, "seq", None) 
    if seq and callable(seq): 
     return seq(b) 

    # Check equality according to type type [sic]. 
    if isinstance(a, basestring): 
     return a == b 
    if isinstance(a, np.ndarray): 
     return np.all(a == b) 
    if isinstance(a, Sequence): 
     return all(nested_equal(x, y) for x, y in zip(a, b)) 
    if isinstance(a, Mapping): 
     if set(a.keys()) != set(b.keys()): 
      return False 
     return all(nested_equal(a[k], b[k]) for k in a.keys()) 
    if isinstance(a, Set): 
     return a == b 
    return a == b 

가정 해쉬 객체가 아니라 안전 평등에 영향을 미치는 방식으로 변경할 수없는 것을 그것을이 dicts을 깰 것이기 때문에와 그러한 객체가 키로 사용 된 경우를 설정합니다.

+0

감사합니다. 유용한 조언입니다. :) – SmCaterpillar