从python列表中选择子列表,从同一元素开始和结束

Qub*_*bix 6 python list python-3.x

我有一个(非常大)列表类似于:

a = ['A', 'B', 'A', 'B', 'A', 'C', 'D', 'E', 'D', 'E', 'D', 'F', 'G', 'A', 'B']
Run Code Online (Sandbox Code Playgroud)

我想从中提取一个列表列表,如:

result = [['A', 'B', 'A', 'B', 'A'], ['D', 'E', 'D', 'E', 'D']]
Run Code Online (Sandbox Code Playgroud)

重复模式可以是不同的,例如,也可以存在间隔,例如:

['A', 'B', 'C', 'A', 'D', 'E', 'A'] (with a 'jump' over two elements)
Run Code Online (Sandbox Code Playgroud)

我写了一个非常简单的代码似乎工作:

tolerance = 2
counter = 0
start, stop = 0, 0
for idx in range(len(a) - 1):
    if a[idx] == a[idx+1] and counter == 0:
        start = idx
        counter += 1
    elif a[idx] == a[idx+1] and counter != 0:
        if tolerance <= 0: 
            stop = idx
        tolerance = 2
    elif a[idx] != a[idx+1]:
        tolerance -= 1
    if start != 0 and stop != 0:
        result = [a[start::stop]]
Run Code Online (Sandbox Code Playgroud)

但是1)它非常麻烦,2)我需要将它应用于非常大的列表,那么是否有更简洁,更快速的方法来实现它?

编辑:正如@Kasramvd正确指出的那样,我需要满足要求的最大集合(最多在起始元素和结束元素之间的跳转容差数量),所以我采取:

['A', 'B', 'A', 'B', 'A'] instead of [ 'B', 'A', 'B' ]
Run Code Online (Sandbox Code Playgroud)

因为前者包括后者.

如果代码可以选择UP到特定容差的元素也是好的,例如,如果容差(元素的最大数量不等于start或end元素)是2,它还应该返回以下集合:

['A', 'A', 'A', 'B', 'A', 'B', 'A', 'C', 'D', 'A']
Run Code Online (Sandbox Code Playgroud)

tolerances0,1和2.

ikk*_*kuh 4

除了子列表结果之外,无需任何额外的列表复制的解决方案:

def sublists(a, tolerance):
    result = []
    index = 0

    while index < len(a):
        curr = a[index]

        for i in range(index, len(a)):
            if a[i] == curr:
                end = i
            elif i - end > tolerance:
                break

        if index != end:
            result.append(a[index:end+1])
        index += end - index + 1

    return result
Run Code Online (Sandbox Code Playgroud)

用法简单如下:

a = ['A', 'B', 'A', 'B', 'A', 'C', 'D', 'E', 'D', 'E', 'D', 'F', 'G', 'A', 'B']

sublists(a, 0)  # []
sublists(a, 1)  # [['A', 'B', 'A', 'B', 'A'], ['D', 'E', 'D', 'E', 'D']]
sublists(a, 2)  # [['A', 'B', 'A', 'B', 'A'], ['D', 'E', 'D', 'E', 'D']]
Run Code Online (Sandbox Code Playgroud)

注释中指定的额外要求的可能解决方案:

if i > index and a[i] == a[i-1] == curr:
    end = i - 1
    break
elif a[i] == curr:
    end = i
elif i - end > tolerance:
    break
Run Code Online (Sandbox Code Playgroud)

注意:我还没有对此进行彻底测试。