获取值不为 None 的范围

hen*_*nry 7 python list

目标

我想获取列表中值不为 None 的范围,例如:

test1 = [None, 0, None]
test2 = [2,1,None]
test3 = [None,None,3]
test4 = [1,0,None,0,0,None,None,1,None,0]

res1 = [[1,1]]
res2 = [[0,1]]
res3 = [[2,2]]
res4 = [[0,1],[3,4],[7,7],[9,9]]
Run Code Online (Sandbox Code Playgroud)

我尝试过的

这是我超长的实现,它并不完美工作......

def get_not_None_ranges(list_):
    # Example [0, 2, None, 1, 4] -> [[0, 1], [3, 4]]
    r = []
    end_i = len(list_)-1
    if list_[0] == None:
        s = None
    else:
        s = 0
        
    for i, elem in enumerate(list_):
        if s != None:
            if elem == None and end_i != i:
                r.append([s,i-1])
                s = i+1
            if end_i == i:
                if s > i:
                    r=r
                elif s==i and elem == None:
                    r=r
                else:
                    r.append([s,i])
        else:
            if elem != None:
                s = i
            if end_i == i:
                if s > i:
                    r=r
                else:
                    r.append([s,i])
            
    return r 
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,结果有时是错误的:

print(get_not_None_ranges(test1))
print(get_not_None_ranges(test2))
print(get_not_None_ranges(test3))
print(get_not_None_ranges(test4))


[[1, 2]]
[[0, 2]]
[[2, 2]]
[[0, 1], [3, 4], [6, 5], [7, 7], [9, 9]]
Run Code Online (Sandbox Code Playgroud)

所以,我想知道你们是否知道更好的方法来实现这一目标?

Dan*_*ejo 4

使用itertools.groupby

from itertools import groupby

test1 = [None, 0, None]
test2 = [2, 1, None]
test3 = [None, None, 3]
test4 = [1, 0, None, 0, 0, None, None, 1, None, 0]


def get_not_None_ranges(lst):
    result = []
    for key, group in groupby(enumerate(lst), key=lambda x: x[1] is not None):
        if key:
            index, _ = next(group)
            result.append([index, index + sum(1 for _ in group)])
    return result


print(get_not_None_ranges(test1))
print(get_not_None_ranges(test2))
print(get_not_None_ranges(test3))
print(get_not_None_ranges(test4))
Run Code Online (Sandbox Code Playgroud)

输出

[[1, 1]]
[[0, 1]]
[[2, 2]]
[[0, 1], [3, 4], [7, 7], [9, 9]]
Run Code Online (Sandbox Code Playgroud)