Live data from Hacker News

Pythonic monotonic

nedbatchelder.com

61–64 of 64 posts

Re: Pythonic monotonic

#61
self documenting code ;-)

  def descending(lst):
    if len(lst)  second:
        return False
    if first = temp[-1] and status >= 0:
            if v > temp[-1]:
                status = 1
            temp.append(v)    
            continue
        if v 

Re: Pythonic monotonic

#62
Here’s mine. Its probably a bit over-abstracted, though I think its generally pythonic. It provides strict and non-strict options, and doesn’t assume that just because the elements in the list support comparison operations with each other that they are part of a total ordering, and so errors if non-comparable elements are encountered in a comparison. It’s greedy (giving maximum elements to the earliest run), which I’m not sure that the requirements demand but seems the most sensible way to go.

    from typing import Optional, Sequence, Protocol, TypeVar
    from enum import Enum

    T = TypeVar("T")

    class SupportsLessAndEq(Protocol):
        def __lt__(self: T, other: T) -> bool:
            ...
        
        def __eq__(self: T, other: T) -> bool:
            ...

    U = TypeVar("U", bound=SupportsLessAndEq)

    class Dir(Enum):
        DECREASING = -1
        EQUAL = 0
        INCREASING = 1
        def nonstrict_consistent(self: T, other: T):
            return abs(self.value-other.value)  Optional[Dir]:
        return Dir.INCREASING if x  Dir:
        result = try_cmp(x,y)
        if result is None:
            raise ValueError(f"Cannot compare {repr(x)} with {repr(y)}")
        return result

    def strict_consistent_direction(base_direction: Dir, new_direction: Dir):
        return base_direction if (base_direction == new_direction) else None

    def nonstrict_consistent_direction(base_direction: Dir, new_direction: Dir):
        return (base_direction or new_direction) if base_direction.nonstrict_consistent(new_direction) else None

    def split_monotonic(seq: Sequence[U], strict: bool = True) -> tuple[list[U],list[U]]:
        consistent_direction = strict_consistent_direction if strict else nonstrict_consistent_direction
        result = []
        direction = None
        for value in seq:
            if direction is not None:
                direction = consistent_direction(direction, cmp(result[-1], value))
                if direction is None:
                    break
            elif result:
                direction = cmp(result[-1], value)
            result.append(value)
        return (sorted(result), list(seq[len(result):]))

    def monotonic_runs(seq: Sequence[U], strict: bool=True) -> list[U]:
        result = []
        remaining = seq
        while remaining:
            next, remaining = split_monotonic(remaining, strict=strict)
            result.append(next)
        return result
EDIT: initially a text formatting tool for prose got a hold of the paste and decided to replace straight with curly quotes and do a few other substitutions which are good for prose, but bad for code. I think I cleaned them all up now.

Re: Pythonic monotonic

#64
If-statements are for the weak :-)

This uses numpy, but it's the shortest answer presented thus far.

    In [1]: from itertools import chain, zip_longest
       ...: import numpy as np
       ...:
       ...: def f(l):
       ...:     a = np.array([-np.inf, *l])
       ...:     up = a[:-1] 
Post reply on HN