pythondeclarative-programming

Python declarative loop refactor (need access multiple elements)


Hi I have this piece of code and trying to refactor it to be declarative. But AFAIK, all declarative methods like map() reduce() filter() will loop through each element of the container, not a few like this

def arrayCheck(nums):

    # Note: iterate with length-2, so can use i+1 and i+2 in the loop
    for i in range(len(nums)-2):
        # Check in sets of 3 if we have 1,2,3 in a row
        if nums[i]==1 and nums[i+1]==2 and nums[i+2]==3:
            return True
    return False

So how to write this code, declarative way?


Solution

  • First, you can use a zip to rewrite your loop:

    def array_check(nums):
        for a, b, c in zip(nums, nums[1:], nums[2:]):
            if a == 1 and b == 2 and c == 3:
                return True
        return False
    

    Then, use the tuple comparison:

    def array_check(nums):
        for a, b, c in zip(nums, nums[1:], nums[2:]):
            if (a, b, c) == (1, 2, 3):
                return True
        return False
    

    And then the any builtin:

    def array_check(nums):
        return any((a, b, c) == (1, 2, 3) for a, b, c in zip(nums, nums[1:], nums[2:]))
    

    Test:

    >>> array_check([1,3,4,1,2,3,5])
    True
    >>> array_check([1,3,4,1,3,5])
    False
    

    Note: for a faster version, see @juanpa.arrivillaga comment below.


    If you want to mimic functional style:

    import operator, functools
    
    def array_check(nums):
        return any(map(functools.partial(operator.eq, (1,2,3)), zip(nums, nums[1:], nums[2:])))
    

    But that's really unpythonic!