목록의 모든 요소가 동일한 지 확인하십시오
다음 기능이 필요합니다.
입력 :list
출력 :
True
입력 목록의 모든 요소가 표준 항등 연산자를 사용하여 서로 같은 것으로 평가되는 경우;False
그렇지 않으면.
성능 : 물론 불필요한 오버 헤드가 발생하지 않는 것을 선호합니다.
나는 그것이 최선일 것이라고 생각한다.
- 목록을 반복
- 인접한 요소를 비교
- 그리고
AND
모든 결과 부울 값
그러나 가장 파이썬적인 방법이 무엇인지 잘 모르겠습니다.
편집 :
모든 위대한 답변에 감사드립니다. 나는 여러 등급을 매겼으며 @KennyTM와 @Ivo van der Wijk 솔루션 중에서 선택하기가 정말 어려웠다.
단락 기능이 없으면 초기 요소가 같지 않은 긴 입력 (~ 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]에 대한 값을 사용할 수 있습니다.
이 방법은 len(set(x))==1
긴 목록 보다 빠릅니다 (단락 사용).
def constantList(x):
return x and [x[0]]*len(x) == x
이것은 간단한 방법입니다.
result = mylist and all(mylist[0] == elem for elem in mylist)
이것은 약간 더 복잡하고, 함수 호출 오버 헤드가 발생하지만, 시맨틱은보다 명확하게 설명되어 있습니다.
def all_identical(seq):
if not seq:
# empty list is False.
return False
first = seq[0]
return all(first == elem for elem in seq)
모든 요소가 첫 번째 요소와 같은지 확인하십시오.
np.allclose(array, array[0])
의심 할 여지없이 이것은 "가장 파이썬적인"것입니다.
>>> falseList = [1,2,3,4]
>>> trueList = [1, 1, 1]
>>>
>>> def testList(list):
... for item in list[1:]:
... if item != list[0]:
... return False
... return True
...
>>> testList(falseList)
False
>>> testList(trueList)
True
트릭을 할 것입니다.
좀 더 읽기 쉬운 (물론 효율적이지 않은) 것에 관심이 있다면 다음을 시도해보십시오.
def compare_lists(list1, list2):
if len(list1) != len(list2): # Weed out unequal length lists.
return False
for item in list1:
if item not in list2:
return False
return True
a_list_1 = ['apple', 'orange', 'grape', 'pear']
a_list_2 = ['pear', 'orange', 'grape', 'apple']
b_list_1 = ['apple', 'orange', 'grape', 'pear']
b_list_2 = ['apple', 'orange', 'banana', 'pear']
c_list_1 = ['apple', 'orange', 'grape']
c_list_2 = ['grape', 'orange']
print compare_lists(a_list_1, a_list_2) # Returns True
print compare_lists(b_list_1, b_list_2) # Returns False
print compare_lists(c_list_1, c_list_2) # Returns False
나는 할 것이다 :
not any((x[i] != x[i+1] for i in range(0, len(x)-1)))
조건을 any
찾으면 iterable 검색 을 중지 True
합니다.
reduce()
with를 사용 하는 경우 lambda
. 여기 개인적으로 생각하는 작동 코드가 다른 답변보다 훨씬 좋습니다.
reduce(lambda x, y: (x[1]==y, y), [2, 2, 2], (True, 2))
모든 항목이 같거나 같지 않은 경우 첫 번째 값이 부울 인 truple을 반환합니다.
목록을 세트로 변환 한 다음 세트의 요소 수를 찾으십시오. 결과가 1이면 동일한 요소가 있고 그렇지 않으면 목록의 요소가 동일하지 않습니다.
list1 = [1,1,1]
len(set(list1))
>1
list1 = [1,2,3]
len(set(list1)
>3
>>> a = [1, 2, 3, 4, 5, 6]
>>> z = [(a[x], a[x+1]) for x in range(0, len(a)-1)]
>>> z
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
# Replacing it with the test
>>> z = [(a[x] == a[x+1]) for x in range(0, len(a)-1)]
>>> z
[False, False, False, False, False]
>>> if False in z : Print "All elements are not equal"
def allTheSame(i):
j = itertools.groupby(i)
for k in j: break
for k in j: return False
return True
"모두"가없는 Python 2.4에서 작동합니다.
지도와 람다를 사용할 수 있습니다
lst = [1,1,1,1,1,1,1,1,1]
print all(map(lambda x: x == lst[0], lst[1:]))
또는 diff
numpy의 방법을 사용하십시오 .
import numpy as np
def allthesame(l):
return np.all(np.diff(l)==0)
그리고 전화 :
print(allthesame([1,1,1]))
산출:
True
또는 numpy의 diff 방법을 사용하십시오.
import numpy as np
def allthesame(l):
return np.unique(l).shape[0]<=1
그리고 전화 :
print(allthesame([1,1,1]))
산출:
진실
넌 할 수있어:
reduce(and_, (x==yourList[0] for x in yourList), True)
파이썬으로 연산자를 가져올 수 있다는 것은 상당히 성가신 일입니다 operator.and_
. python3부터는을 가져와야 functools.reduce
합니다.
(이 방법은 같지 않은 값을 찾으면 깨지지 않지만 전체 목록을 계속 검토하므로이 방법을 사용하면 안됩니다.이 방법은 완전성에 대한 답변으로 여기에 포함됩니다.)
lambda lst: reduce(lambda a,b:(b,b==a[0] and a[1]), lst, (lst[0], True))[1]
다음은 단락됩니다 :
all(itertools.imap(lambda i:yourlist[i]==yourlist[i+1], xrange(len(yourlist)-1)))
목록을 세트로 변경하십시오. 그런 다음 세트의 크기가 1 인 경우 동일해야합니다.
if len(set(my_list)) == 1:
순수한 파이썬 재귀 옵션도 있습니다.
def checkEqual(lst):
if len(lst)==2 :
return lst[0]==lst[1]
else:
return lst[0]==lst[1] and checkEqual(lst[1:])
그러나 어떤 이유로 든 어떤 경우에는 다른 옵션보다 두 배의 속도가 느립니다. C 언어 사고 방식에서 나는 이것이 더 빠를 것으로 예상했지만 그렇지 않습니다!
다른 단점은 파이썬에는 재귀 제한이 있으며이 경우 조정해야한다는 것입니다. 예를 들어 this 를 사용 하십시오 .
.nunique()
목록에서 고유 항목 수를 찾는 데 사용할 수 있습니다 .
def identical_elements(list):
series = pd.Series(list)
if series.nunique() == 1: identical = True
else: identical = False
return identical
identical_elements(['a', 'a'])
Out[427]: True
identical_elements(['a', 'b'])
Out[428]: False
당신은 set
그것을 사용 하고 반복적 인 요소를 제거 할 수 있습니다 . 그런 다음 1 요소가 있는지 확인하십시오.
if set(your_list) == 1:
print('all ements are equal')
참고 URL : https://stackoverflow.com/questions/3844801/check-if-all-elements-in-a-list-are-identical
'Programing' 카테고리의 다른 글
FROM 절에서 업데이트 대상 테이블을 지정할 수 없습니다 (0) | 2020.03.02 |
---|---|
날짜에 대해 Math.Min 및 Math.Max에 해당합니까? (0) | 2020.03.02 |
SQL Server 2008에서 앞에 오는 0으로 문자열을 채우면 길이는 3 자입니다. (0) | 2020.03.02 |
터미널에서 MySQL로 데이터베이스를 가져 오려면 어떻게해야합니까? (0) | 2020.03.02 |
파이썬 : 예외를 무시하고 진행하는 방법? (0) | 2020.03.02 |