목록이 이미 정렬되어 있는지 확인하는 파이썬 방법이 ASC
또는DESC
listtimestamps = [1, 2, 3, 5, 6, 7]
같은 isttimestamps.isSorted()
그 반환 True
또는 False
.
일부 메시지의 타임 스탬프 목록을 입력하고 트랜잭션이 올바른 순서로 나타나는지 확인하고 싶습니다.
답변
실제로 우리는 anijhaw가 찾고있는 해답을주지 않습니다. 하나의 라이너는 다음과 같습니다.
all(l[i] <= l[i+1] for i in xrange(len(l)-1))
파이썬 3의 경우 :
all(l[i] <= l[i+1] for i in range(len(l)-1))
답변
난 그냥 사용할거야
if sorted(lst) == lst:
# code here
매우 큰 목록이 아닌 경우 사용자 정의 함수를 만들 수 있습니다.
정렬되지 않은 경우 정렬하려는 경우 확인을 잊고 정렬하십시오.
lst.sort()
그것에 대해 너무 많이 생각하지 마십시오.
사용자 정의 기능을 원하면 다음과 같은 작업을 수행 할 수 있습니다
def is_sorted(lst, key=lambda x: x):
for i, el in enumerate(lst[1:]):
if key(el) < key(lst[i]): # i is the index of the previous element
return False
return True
목록이 이미 정렬되어 있으면 for
루프 (O (n) 입니다!)이므로 대부분 정렬되지 않을 것으로 예상하지 않는 한, 다시 목록을 정렬하십시오.
답변
이 반복자 형식은 정수 색인 작성보다 10-15 % 빠릅니다.
# python2 only
if str is bytes:
from itertools import izip as zip
def is_sorted(l):
return all(a <= b for a, b in zip(l, l[1:]))
답변
이것을 구현하는 아름다운 방법 imap
은 itertools
다음 에서 함수 를 사용하는 것입니다 .
from itertools import imap, tee
import operator
def is_sorted(iterable, compare=operator.le):
a, b = tee(iterable)
next(b, None)
return all(imap(compare, a, b))
이 구현은 빠르며 모든 iterable에서 작동합니다.
답변
나는 벤치 마크를 실행 하고 . 이 벤치 마크는 MacBook Pro 2010 13 “(Core2 Duo 2.66GHz, 4GB 1067MHz DDR3 RAM, Mac OS X 10.6.5)에서 실행되었습니다.sorted(lst, reverse=True) == lst
긴 목록에 대한 가장 빠른, 그리고 all(l[i] >= l[i+1] for i in xrange(len(l)-1))
가장 빠른 짧은 목록에 대한이었다
업데이트 : 스크립트를 수정하여 자신의 시스템에서 직접 실행할 수 있습니다. 이전 버전에는 버그가있었습니다. 또한 정렬 된 입력과 정렬되지 않은 입력을 모두 추가했습니다.
- 짧은 정렬 목록에 가장 적합 :
all(l[i] >= l[i+1] for i in xrange(len(l)-1))
- 긴 정렬 목록에 가장 적합 :
sorted(l, reverse=True) == l
- 분류되지 않은 짧은 목록에 가장 적합 :
all(l[i] >= l[i+1] for i in xrange(len(l)-1))
- 정렬되지 않은 긴 목록에 가장 적합 :
all(l[i] >= l[i+1] for i in xrange(len(l)-1))
따라서 대부분의 경우 확실한 승자가 있습니다.
업데이트 : aaronsterling의 답변 (# 6 및 # 7)은 실제로 모든 경우에서 가장 빠릅니다. # 7은 키를 조회 할 수있는 간접 계층이 없기 때문에 가장 빠릅니다.
#!/usr/bin/env python
import itertools
import time
def benchmark(f, *args):
t1 = time.time()
for i in xrange(1000000):
f(*args)
t2 = time.time()
return t2-t1
L1 = range(4, 0, -1)
L2 = range(100, 0, -1)
L3 = range(0, 4)
L4 = range(0, 100)
# 1.
def isNonIncreasing(l, key=lambda x,y: x >= y):
return all(key(l[i],l[i+1]) for i in xrange(len(l)-1))
print benchmark(isNonIncreasing, L1) # 2.47253704071
print benchmark(isNonIncreasing, L2) # 34.5398209095
print benchmark(isNonIncreasing, L3) # 2.1916718483
print benchmark(isNonIncreasing, L4) # 2.19576501846
# 2.
def isNonIncreasing(l):
return all(l[i] >= l[i+1] for i in xrange(len(l)-1))
print benchmark(isNonIncreasing, L1) # 1.86919999123
print benchmark(isNonIncreasing, L2) # 21.8603689671
print benchmark(isNonIncreasing, L3) # 1.95684289932
print benchmark(isNonIncreasing, L4) # 1.95272517204
# 3.
def isNonIncreasing(l, key=lambda x,y: x >= y):
return all(key(a,b) for (a,b) in itertools.izip(l[:-1],l[1:]))
print benchmark(isNonIncreasing, L1) # 2.65468883514
print benchmark(isNonIncreasing, L2) # 29.7504849434
print benchmark(isNonIncreasing, L3) # 2.78062295914
print benchmark(isNonIncreasing, L4) # 3.73436689377
# 4.
def isNonIncreasing(l):
return all(a >= b for (a,b) in itertools.izip(l[:-1],l[1:]))
print benchmark(isNonIncreasing, L1) # 2.06947803497
print benchmark(isNonIncreasing, L2) # 15.6351969242
print benchmark(isNonIncreasing, L3) # 2.45671010017
print benchmark(isNonIncreasing, L4) # 3.48461818695
# 5.
def isNonIncreasing(l):
return sorted(l, reverse=True) == l
print benchmark(isNonIncreasing, L1) # 2.01579380035
print benchmark(isNonIncreasing, L2) # 5.44593787193
print benchmark(isNonIncreasing, L3) # 2.01813793182
print benchmark(isNonIncreasing, L4) # 4.97615599632
# 6.
def isNonIncreasing(l, key=lambda x, y: x >= y):
for i, el in enumerate(l[1:]):
if key(el, l[i-1]):
return False
return True
print benchmark(isNonIncreasing, L1) # 1.06842684746
print benchmark(isNonIncreasing, L2) # 1.67291283607
print benchmark(isNonIncreasing, L3) # 1.39491200447
print benchmark(isNonIncreasing, L4) # 1.80557894707
# 7.
def isNonIncreasing(l):
for i, el in enumerate(l[1:]):
if el >= l[i-1]:
return False
return True
print benchmark(isNonIncreasing, L1) # 0.883186101913
print benchmark(isNonIncreasing, L2) # 1.42852401733
print benchmark(isNonIncreasing, L3) # 1.09229516983
print benchmark(isNonIncreasing, L4) # 1.59502696991
답변
나는 이것을 할 것입니다 ([Aaron Sterling, Wai Yip Tung, Paul McGuire의 일종 ) 및 대부분 Armin Ronacher )
from itertools import tee, izip
def pairwise(iterable):
a, b = tee(iterable)
next(b, None)
return izip(a, b)
def is_sorted(iterable, key=lambda a, b: a <= b):
return all(key(a, b) for a, b in pairwise(iterable))
한 가지 좋은 점은 시리즈에 대해 두 번째 반복 가능을 구현할 필요가 없다는 것입니다 (목록 조각과는 달리).
답변
numpy.diff ()를 기반으로 한이 라이너를 사용합니다.
def issorted(x):
"""Check if x is sorted"""
return (numpy.diff(x) >= 0).all() # is diff between all consecutive entries >= 0?
나는 다른 방법에 대해 실제로 시간을 정하지 않았지만 numpy.diff의 루프가 아마도 C (n-1 빼기 다음에 n이 있기 때문에) 특히 순수한 n에 대해 순수한 파이썬 방법보다 빠르다고 가정합니다. -1 비교).
그러나 x가 부호없는 int 인 경우주의해야합니다. 이로 인해 numpy.diff ()에서 자동 정수 언더 플로가 발생하여 오 탐지가 발생할 수 있습니다. 수정 된 버전은 다음과 같습니다.
def issorted(x):
"""Check if x is sorted"""
try:
if x.dtype.kind == 'u':
# x is unsigned int array, risk of int underflow in np.diff
x = numpy.int64(x)
except AttributeError:
pass # no dtype, not an array
return (numpy.diff(x) >= 0).all()