Pythonic way to determine whether not null list entries are 'continuous'

后端 未结 11 1203
渐次进展
渐次进展 2021-02-01 01:35

I\'m looking for a way to easily determine if all not None items in a list occur in a single continuous slice. I\'ll use integers as examples of not None items

11条回答
  •  既然无缘
    2021-02-01 02:10

    My first approach was to use variables to keep track ...

    ...this ends up with a highly nested and very difficult to follow series of if/else statements embedded in a for loop...

    No! Actually you need only one variable. Thinking this problem in the view of Finite State Machine(FSM) with your approach will lead to a quite nice solution.

    We call the state p. At first, p is 0. Then we start walking between the states.

    FSM

    When all the elements in the list is examinated and still don't fail then the answer is True.

    One version that encode the translation table in a dict

    def contiguous(s, _D={(0,0):0, (0,1):1, (1,0):2, (1,1):1, (2,0):2, (2,1):3}):
        p = 0
        for x in s:
            p = _D[p, int(x is not None)]
            if p >= 3: return False
        return True
    

    Another version that use if statement:

    def contiguous(s):
        p = 0
        for x in s:
            if x is None and p == 1 or x is not None and (p == 0 or p == 2):
                p += 1
            if p >= 3: return False
        return True
    

    So my point is that using if and for are still pythonic.

    update

    I found another way to encode the FSM. We can pack the translation table into a 12bit integer.

    def contiguous(s):
        p = 0
        for x in s:
            p = (3684 >> (4*p + 2*(x!=None))) & 3
            if p >= 3: return False
        return True
    

    Here 3684, the magic number, can be obtained by:

        _D[p,a]     3  2  1  2  1  0
             p      2  2  1  1  0  0
             a      1  0  1  0  1  0
    bin(3684) = 0b 11 10 01 10 01 00 
    

    The readability is not as good as other version but it's faster since it avoids dictionary lookup. The second version is as fast as this but this encoding idea can be generalized to solve more problems.

提交回复
热议问题