Programing

순서가없는 두 목록이 동일한 지 확인하십시오

lottogame 2020. 4. 18. 09:29
반응형

순서가없는 두 목록이 동일한 지 확인하십시오


정렬되지 않은목록에 동일한 요소가 포함되어 있는지 확인하는 쉽고 빠른 방법을 찾고 있습니다.

예를 들면 다음과 같습니다.

['one', 'two', 'three'] == ['one', 'two', 'three'] :  true
['one', 'two', 'three'] == ['one', 'three', 'two'] :  true
['one', 'two', 'three'] == ['one', 'two', 'three', 'three'] :  false
['one', 'two', 'three'] == ['one', 'two', 'three', 'four'] :  false
['one', 'two', 'three'] == ['one', 'two', 'four'] :  false
['one', 'two', 'three'] == ['one'] :  false

지도를 사용하지 않고이 작업을 수행하고 싶습니다.


파이썬에는 정렬되지 않은 (해시 가능한) 것들의 정렬되지 않은 콜렉션에 대한 내장 데이터 유형이 set있습니다. 두 목록을 모두 세트로 변환하면 비교가 정렬되지 않습니다.

set(x) == set(y)

에 대한 설명서 set


편집 : @mdwhatcott는 중복을 확인하고 싶다고 지적합니다. set이를 무시하므로 각 목록의 항목 수를 추적하는 유사한 데이터 구조가 필요합니다. 이것을 다중 집합 이라고합니다 . 표준 라이브러리에서 가장 근사치는 다음과 collections.Counter같습니다.

>>> import collections
>>> compare = lambda x, y: collections.Counter(x) == collections.Counter(y)
>>> 
>>> compare([1,2,3], [1,2,3,3])
False
>>> compare([1,2,3], [1,2,3])
True
>>> compare([1,2,3,3], [1,2,2,3])
False
>>> 

예제와 같이 요소가 항상 거의 정렬되면 내장 .sort()( timsort )이 빠릅니다.

>>> a = [1,1,2]
>>> b = [1,2,2]
>>> a.sort()
>>> b.sort()
>>> a == b
False

제자리에서 정렬하지 않으려면을 사용할 수 있습니다 sorted().

실제로 항상 빨리 다음 수 있습니다 collections.Counter()(점근에도 불구하고 O(n)시간이 더 좋은 것을 O(n*log(n))위해 .sort()). 그것을 측정하십시오; 중요하다면.


sorted(x) == sorted(y)

여기에서 복사 : 순서가없는 두 목록이 같은지 확인

나는 이것이이 질문에 대한 가장 좋은 대답이라고 생각합니다.

  1. 이 답변 에서 지적한대로 카운터를 사용하는 것보다 낫습니다.
  2. x.sort ()는 부작용 x 인 x를 정렬합니다. sorted (x)는 새 목록을 반환합니다.

동일한 요소가 포함되어 있는지 확인하고 싶지만 순서는 신경 쓰지 않습니다.

세트를 사용할 수 있습니다 :

>>> set(['one', 'two', 'three']) == set(['two', 'one', 'three'])
True

그러나 설정된 객체 자체에는 각 고유 값의 인스턴스가 하나만 포함되며 순서는 유지되지 않습니다.

>>> set(['one', 'one', 'one']) == set(['one'])
True

따라서 중복 / 길이 추적이 중요한 경우 길이를 확인하고 싶을 수도 있습니다.

def are_eq(a, b):
    return set(a) == set(b) and len(a) == len(b)

컬렉션 라이브러리를 사용하지 않으려는 경우 항상 다음과 같이 할 수 있습니다. 목록 ab목록이 있으면 다음은 일치하는 요소 수를 반환합니다 (순서를 고려함).

sum([1 for i,j in zip(a,b) if i==j])

따라서,

len(a)==len(b) and len(a)==sum([1 for i,j in zip(a,b) if i==j])

것이다 True리스트 모두가 동일하면, 동일한 구성 요소를 포함하고, 동일한 순서. False그렇지 않으면.

따라서 컬렉션 라이브러리없이 위의 첫 번째 응답과 같은 비교 기능을 정의 할 수 있습니다.

compare = lambda a,b: len(a)==len(b) and len(a)==sum([1 for i,j in zip(a,b) if i==j])

>>> compare([1,2,3], [1,2,3,3])
False
>>> compare([1,2,3], [1,2,3])
True
>>> compare([1,2,3], [1,2,4])
False

위의 질문에 대한 한 가지 대답은 다음과 같습니다.

두 목록을 list1과 list2로 설정하고 요구 사항은 두 목록이 동일한 요소를 갖는지 확인하는 것입니다.

if ((len(list1) == len(list2)) and
   (all(i in list2 for i in list1))):
    print 'True'
else:
    print 'False'

위의 코드는 필요에 따라 작동합니다. 즉 list1의 모든 요소가 list2에 있고 그 반대인지 여부입니다.

그러나 list1의 모든 요소가 list2에 있는지 여부를 확인하려면 아래 코드 조각 만 사용해야합니다.

if all(i in list2 for i in list1):
    print 'True'
else:
    print 'False'

차이점은 list2에 list1의 모든 요소와 함께 일부 추가 요소가 포함 된 경우 나중에 True를 인쇄한다는 것입니다. 간단히 말해, list2에 추가 요소가 있는지 여부에 관계없이 list1의 모든 요소가 list2에 있어야합니다.


목록의 문자열 표현을 가져 와서 비교하는 것은 어떻습니까?

>>> l1 = ['one', 'two', 'three']
>>> l2 = ['one', 'two', 'three']
>>> l3 = ['one', 'three', 'two']
>>> print str(l1) == str(l2)
True
>>> print str(l1) == str(l3)
False

이미 목록의 크기가 동일하다는 것을 알고 있다고 가정하면 다음은 두 벡터가 정확히 동일한 경우에만 (순서를 포함하여) True를 보장합니다.

functools.reduce(lambda b1,b2: b1 and b2, map(lambda e1,e2: e1==e2, listA, ListB), True)

예:

>>> from functools import reduce
>>> def compvecs(a,b):
...     return reduce(lambda b1,b2: b1 and b2, map(lambda e1,e2: e1==e2, a, b), True)
... 
>>> compvecs(a=[1,2,3,4], b=[1,2,4,3])
False
>>> compvecs(a=[1,2,3,4], b=[1,2,3,4])
True
>>> compvecs(a=[1,2,3,4], b=[1,2,4,3])
False
>>> compare_vectors(a=[1,2,3,4], b=[1,2,2,4])
False
>>> 

참고 URL : https://stackoverflow.com/questions/9623114/check-if-two-unorder-lists-are-equal

반응형