Oto wariant, który akceptuje zarówno zmaterializowane, jak i niezmaterializowane sekwencje. Automatycznie określa, czy to jest monotonic
, a jeśli tak, to jego kierunek (tj. increasing
Lub decreasing
) i czy strict
. Aby pomóc czytelnikowi, zamieszczono komentarze w tekście. Podobnie w przypadku przypadków testowych dostarczonych na końcu.
def isMonotonic(seq):
"""
seq.............: - A Python sequence, materialized or not.
Returns.........:
(True,0,True): - Mono Const, Strict: Seq empty or 1-item.
(True,0,False): - Mono Const, Not-Strict: All 2+ Seq items same.
(True,+1,True): - Mono Incr, Strict.
(True,+1,False): - Mono Incr, Not-Strict.
(True,-1,True): - Mono Decr, Strict.
(True,-1,False): - Mono Decr, Not-Strict.
(False,None,None) - Not Monotonic.
"""
items = iter(seq)
prev_value = next(items, None)
if prev_value == None: return (True,0,True)
isSequenceExhausted = True
curr_value = prev_value
for item in items:
isSequenceExhausted = False
if item == prev_value: continue
curr_value = item
break
else:
return (True,0,True) if isSequenceExhausted else (True,0,False)
strict = True
if curr_value > prev_value:
for item in items:
if item < curr_value: return (False,None,None)
if item == curr_value: strict = False
curr_value = item
return (True,+1,strict)
else:
for item in items:
if item > curr_value: return (False,None,None)
if item == curr_value: strict = False
curr_value = item
return (True,-1,strict)
assert isMonotonic([1,2,3,4]) == (True,+1,True)
assert isMonotonic([4,3,2,1]) == (True,-1,True)
assert isMonotonic([-1,-2,-3,-4]) == (True,-1,True)
assert isMonotonic([]) == (True,0,True)
assert isMonotonic([20]) == (True,0,True)
assert isMonotonic([-20]) == (True,0,True)
assert isMonotonic([1,1]) == (True,0,False)
assert isMonotonic([1,-1]) == (True,-1,True)
assert isMonotonic([1,-1,-1]) == (True,-1,False)
assert isMonotonic([1,3,3]) == (True,+1,False)
assert isMonotonic([1,2,1]) == (False,None,None)
assert isMonotonic([0,0,0,0]) == (True,0,False)
Przypuszczam, że to może być więcej Pythonic
, ale jest to trudne, ponieważ zapobiega tworzeniu kolekcji pośrednich (np list
, genexps
itp); a także stosuje podejście a fall/trickle-through
i short-circuit
do filtrowania różnych przypadków: Np. sekwencje krawędzi (takie jak sekwencje puste lub jednoelementowe; lub sekwencje ze wszystkimi identycznymi elementami); Rozpoznawanie rosnącej lub malejącej monotoniczności, ścisłości i tak dalej. Mam nadzieję, że to pomoże.