[python] 목록의 모든 요소가 동일한 지 확인하십시오
다음 기능이 필요합니다.
입력 :list
출력 :
True
입력 목록의 모든 요소가 표준 항등 연산자를 사용하여 서로 같은 것으로 평가되는 경우;False
그렇지 않으면.
공연 : 물론 불필요한 오버 헤드가 발생하지 않는 것을 선호합니다.
나는 그것이 최선일 것이라고 생각한다.
- 목록을 반복
- 인접한 요소를 비교
- 그리고
AND
모든 결과 부울 값
그러나 가장 파이썬적인 방법이 무엇인지 잘 모르겠습니다.
단락 기능이 없으면 초기 요소가 같지 않은 긴 입력 (~ 50 개 이상의 요소)에 대해서만 문제가됩니다. 이 문제가 자주 발생하는 경우 (목록의 길이에 따라 다름) 단락이 필요합니다. 최고의 단락 알고리즘은 @KennyTM 인 것 같습니다 checkEqual1
. 그러나 이것에 대한 상당한 비용을 지불합니다.
- 거의 동일한 성능의 목록에서 최대 20 배
- 짧은 목록에서 최대 2.5 배 성능
초기에 같지 않은 요소를 가진 긴 입력이 발생하지 않거나 충분히 드물게 발생하는 경우 단락이 필요하지 않습니다. 그런 다음 @Ivo van der Wijk 솔루션이 가장 빠릅니다.
답변
일반적인 방법 :
def checkEqual1(iterator):
iterator = iter(iterator)
try:
first = next(iterator)
except StopIteration:
return True
return all(first == rest for rest in iterator)
짧막 한 농담:
def checkEqual2(iterator):
return len(set(iterator)) <= 1
또한 하나의 라이너 :
def checkEqual3(lst):
return lst[1:] == lst[:-1]
3 가지 버전의 차이점은 다음과 같습니다.
- 에서
checkEqual2
내용 해쉬해야합니다. checkEqual1
그리고checkEqual2
어떤 반복자를 사용할 수 있지만,checkEqual3
일련의 입력, 목록 또는 튜플 같은 일반적으로 콘크리트 용기를 취해야합니다.checkEqual1
차이가 발견되는 즉시 중지합니다.checkEqual1
더 많은 Python 코드가 포함되어 있기 때문에 처음에 많은 항목이 동일한 경우 효율성이 떨어집니다.- 이후
checkEqual2
와checkEqual3
항상 O (N) 복사 작업을 수행 할 귀하의 의견의 대부분은 False를 반환한다면, 그들은 오래 걸릴 수 있습니다. - 의 경우
checkEqual2
와checkEqual3
는에서 비교 적응하기 힘들어a == b
하는 방법에 대해a is b
.
timeit
결과는 Python 2.7 및 (s1, s4, s7, s9 만 True를 반환해야 함)
s1 = [1] * 5000
s2 = [1] * 4999 + [2]
s3 = [2] + [1]*4999
s4 = [set([9])] * 5000
s5 = [set([9])] * 4999 + [set([10])]
s6 = [set([10])] + [set([9])] * 4999
s7 = [1,1]
s8 = [1,2]
s9 = []
우리는 얻는다
| checkEqual1 | checkEqual2 | checkEqual3 | checkEqualIvo | checkEqual6502 |
|-----|-------------|-------------|--------------|---------------|----------------|
| s1 | 1.19 msec | 348 usec | 183 usec | 51.6 usec | 121 usec |
| s2 | 1.17 msec | 376 usec | 185 usec | 50.9 usec | 118 usec |
| s3 | 4.17 usec | 348 usec | 120 usec | 264 usec | 61.3 usec |
| | | | | | |
| s4 | 1.73 msec | | 182 usec | 50.5 usec | 121 usec |
| s5 | 1.71 msec | | 181 usec | 50.6 usec | 125 usec |
| s6 | 4.29 usec | | 122 usec | 423 usec | 61.1 usec |
| | | | | | |
| s7 | 3.1 usec | 1.4 usec | 1.24 usec | 0.932 usec | 1.92 usec |
| s8 | 4.07 usec | 1.54 usec | 1.28 usec | 0.997 usec | 1.79 usec |
| s9 | 5.91 usec | 1.25 usec | 0.749 usec | 0.407 usec | 0.386 usec |
노트 :
# http://stackoverflow.com/q/3844948/
def checkEqualIvo(lst):
return not lst or lst.count(lst[0]) == len(lst)
# http://stackoverflow.com/q/3844931/
def checkEqual6502(lst):
return not lst or [lst[0]]*len(lst) == lst
답변
시퀀스 (반복 가능하지 않음)에서 작동하는 set ()을 사용하는 것보다 빠른 해결책은 단순히 첫 번째 요소를 계산하는 것입니다. 이것은 목록이 비어 있지 않은 것으로 가정합니다 (그러나 빈 목록에서 결과를 확인하고 결정하는 것은 쉽지 않습니다)
x.count(x[0]) == len(x)
몇 가지 간단한 벤치 마크 :
>>> timeit.timeit('len(set(s1))<=1', 's1=[1]*5000', number=10000)
1.4383411407470703
>>> timeit.timeit('len(set(s1))<=1', 's1=[1]*4999+[2]', number=10000)
1.4765670299530029
>>> timeit.timeit('s1.count(s1[0])==len(s1)', 's1=[1]*5000', number=10000)
0.26274609565734863
>>> timeit.timeit('s1.count(s1[0])==len(s1)', 's1=[1]*4999+[2]', number=10000)
0.25654196739196777
답변
가장 간단하고 우아한 방법은 다음과 같습니다.
all(x==myList[0] for x in myList)
(예, 이것은 빈 목록으로도 작동합니다! 이것은 파이썬이 게으른 의미를 가진 몇 안되는 경우 중 하나이기 때문입니다.)
성능과 관련하여 가능한 빠른 시간 내에 실패하므로 무조건 최적입니다.
답변
세트 비교 작업 :
len(set(the_list)) == 1
를 사용 set
하면 모든 중복 요소가 제거됩니다.
답변
목록을 세트로 변환 할 수 있습니다. 세트는 복제본을 가질 수 없습니다. 따라서 원래 목록의 모든 요소가 동일하면 세트에는 하나의 요소 만 있습니다.
if len(sets.Set(input_list)) == 1
// input_list has all identical elements.
답변
가치있는 것을 위해, 이것은 최근 파이썬 아이디어 메일 링리스트 에 나타났습니다 . 이미이 작업을 수행 하는 itertools 레시피 가 있음이 밝혀졌습니다 . 1
def all_equal(iterable):
"Returns True if all the elements are equal to each other"
g = groupby(iterable)
return next(g, True) and not next(g, False)
아마 그것은 아주 잘 수행하고 몇 가지 좋은 속성을 가지고 있습니다.
- 단락 : 첫 번째 같지 않은 항목을 찾 자마자 iterable에서 항목 소비를 중지합니다.
- 항목을 해시 가능하지 않아도됩니다.
- 게으 르며 검사를 수행하기 위해 O (1) 추가 메모리 만 필요합니다.
1 다시 말해, 솔루션을 제공한다고해서 크레딧을받을 수 없으며 심지어 솔루션을 찾 더라도 크레딧을받을 수 없습니다.
답변
이 작업을 수행하는 두 가지 간단한 방법이 있습니다.
set () 사용
목록을 세트로 변환 할 때 중복 요소가 제거됩니다. 따라서 변환 된 세트의 길이가 1이면 모든 요소가 동일 함을 의미합니다.
len(set(input_list))==1
여기에 예가 있습니다
>>> a = ['not', 'the', 'same']
>>> b = ['same', 'same', 'same']
>>> len(set(a))==1 # == 3
False
>>> len(set(b))==1 # == 1
True
all () 사용
입력 목록의 첫 번째 요소를 목록의 다른 모든 요소와 비교 (등가)합니다. 모두 동등한 경우 True가 반환되고, 그렇지 않으면 False가 반환됩니다.
all(element==input_list[0] for element in input_list)
여기에 예가 있습니다
>>> a = [1, 2, 3, 4, 5]
>>> b = [1, 1, 1, 1, 1]
>>> all(number==a[0] for number in a)
False
>>> all(number==b[0] for number in b)
True
PS 전체 목록이 특정 값과 같은지 확인하는 경우 input_list [0]에 대한 값을 사용할 수 있습니다.