순서가없는 두 목록이 동일한 지 확인하십시오
이 질문에는 이미 답변이 있습니다.
정렬되지 않은 두 목록에 동일한 요소가 포함되어 있는지 확인하는 쉽고 빠른 방법을 찾고 있습니다.
예를 들면 다음과 같습니다.
['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)
편집 : @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)
여기에서 복사 : 순서가없는 두 목록이 같은지 확인
나는 이것이이 질문에 대한 가장 좋은 대답이라고 생각합니다.
- 이 답변 에서 지적한대로 카운터를 사용하는 것보다 낫습니다.
- 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)
컬렉션 라이브러리를 사용하지 않으려는 경우 항상 다음과 같이 할 수 있습니다. 목록 a
과 b
목록이 있으면 다음은 일치하는 요소 수를 반환합니다 (순서를 고려함).
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
'Programing' 카테고리의 다른 글
"참조 된 어셈블리에 강력한 이름이 없습니다"오류를 수정하는 방법? (0) | 2020.04.18 |
---|---|
jQuery-확인란 활성화 / 비활성화 (0) | 2020.04.18 |
테이블 이름 및 테이블 스키마를 사용하여 SQL Server 데이터베이스의 모든 트리거를 나열해야합니다. (0) | 2020.04.18 |
Hibernate Validator를 이용한 교차 필드 검증 (JSR 303) (0) | 2020.04.18 |
.htaccess 및 mod_rewrite를 사용하여 SSL / https를 강제 실행 (0) | 2020.04.18 |