Skip to main content
 首页 » 编程设计

python之在python中查找列表的边界

2024年10月25日14emanlee

给出了一个点列表(通过路径算法找到),我对域的进入/退出点感兴趣。域外的点列为 None。示例路径为 [None, 1, 2, None, 3, 4, 5, None],结果应为 [(1,2), (3,5 )]。现在对于边缘情况 [1, 2, None],结果应该是 [(None, 2)],对于镜像情况 [None, 1 , 2],应该是[(1, None)]

没有最后两个加法,我有

[(systems[0], systems[-1]) if not outside else None 
 for outside, systems in [(o, list(sys)) 
 for o, sys in groupby(path, lambda x: x is None)]] 

via IRC :

def find_borders(L): 
    it = iter(L) 
    for item in it: 
        if item is None: 
            continue 
        start = item 
        end = item 
        for item in it: 
            if item is None: 
                break 
            end = item 
        yield (start, end) 

对于通过 IRC 的解决方案,在开始时添加 None 很容易,但如果不在 iter 上添加 peek 基本上是不可能的.

如何实现第二种边缘情况 [None, 1,2] => [(1, None)]

我创建了一个应该有效但无效的解决方案。它给了我一个 IndexError 因为 systems 是一个空列表,这不应该 发生是因为 groupby 保证它不会分组到空列表中。

def find_borders(path): 
    grouped = list(groupby(path, lambda x: x is None)) 
    for index, (o, sys) in enumerate(grouped): 
        systems = list(sys) 
        if index == 0: 
            yield (None, systems[-1]) 
        elif index == len(grouped)-1: 
            yield (systems[0], None) 
        else: 
            yield (systems[0], systems[-1]) 

请您参考如下方法:

tests = [ 
    [None, 1, 2, None, 3, 4, 5, None], 
    [1, 2, None, 3, 4, 5, None], 
    [None,1, 2, None, 3, 4, 5], 
    [1, 2, None, 3, 4, 5], 
    [1, 2, None], 
    [None, 1, 2], 
] 
 
def find_borders(L): 
    it = iter(L) 
 
    start_none = False 
 
    for item in it: 
        if item is None: 
            start_none = True 
            continue 
        if start_none: 
            start = item 
        else: 
            start = None 
 
        end = item 
 
        end_none = False 
 
        for item in it: 
            if item is None: 
                end_none = True 
                break 
            end = item 
        if not end_none: 
            end = None 
        yield (start, end) 
 
        start_none = True 
 
for t in tests: 
    print 
    print t 
    for x in find_borders(t): 
        print x 

结果

[None, 1, 2, None, 3, 4, 5, None] 
(1, 2) 
(3, 5) 
 
[1, 2, None, 3, 4, 5, None] 
(None, 2) 
(3, 5) 
 
[None, 1, 2, None, 3, 4, 5] 
(1, 2) 
(3, None) 
 
[1, 2, None, 3, 4, 5] 
(None, 2) 
(3, None) 
 
[1, 2, None] 
(None, 2) 
 
[None, 1, 2] 
(1, None)