Python declarative loop refactor (need access multiple elements)

Patton :

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?

jferard :

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!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=170395&siteId=1