简体   繁体   English

查找列表中的所有子序列

[英]Find all subsequences in list

I have a list of 1s and 0s as follows:我有一个 1 和 0 的列表,如下所示:

lst = [1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1]

I'm looking for a method that finds all the sequences of 0s within this list and returns their indices, ie:我正在寻找一种方法来查找此列表中的所有0 序列并返回它们的索引,即:

[1, 3]
[8, 9]
[13, 13]
[15, 16]

This answer shows a method of getting the longest sequence, but I can't think of a way to work from it to get all the sequences. 这个答案显示了一种获得最长序列的方法,但我想不出一种方法来获得所有序列。

def f(l):
    _1to0 = [ i+1 for i, (x, y) in enumerate(zip(l[:-1], l[1:])) if y == 0 and x != y ]
    _0to1 = [ i for i, (x, y) in enumerate(zip(l[:-1], l[1:])) if x == 0 and x != y ]
    if l[0] == 0:
      _1to0.insert(0,0)
    if l[-1] == 0:
      _0to1.append(len(l))
    return zip(_1to0, _0to1)
  1. Detect changes 1 -> 0 (starts) and 0 -> 1 (ends)检测变化 1 -> 0(开始)和 0 -> 1(结束)

  2. If start with 0, add a start at indice 0如果从 0 开始,则在索引 0 处添加一个开始

  3. If ends with 0, add an end at the last indice如果以 0 结尾,则在最后一个索引处添加结尾

  4. Combine starts and ends in pairs成对组合开始和结束

    In [1]: list(f([1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1]))
    Out[1]: [(1, 3), (8, 9), (13, 13), (15, 16)]

For Python 3.8 you can modify the first answer in referenced code by using the Walrus operator对于 Python 3.8,您可以使用Walrus 运算符修改引用代码中的第一个答案

Code代码

from itertools import groupby
import operator

lst = [1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1]

r = [(p[1][0][0], p[1][-1][0]) for (x,y) in groupby(enumerate(lst), operator.itemgetter(1)) if (p := (x, list(y)))[0] == 0]
print(r)

Output输出

[(1, 3), (8, 9), (13, 13), (15, 16)]

Explanation解释

Adding a Walrus operator to OP code reference we have:将 Walrus 运算符添加到 OP 代码参考中,我们有:

r = [p for (x,y) in groupby(enumerate(lst), operator.itemgetter(1)) if (p := (x, list(y)))[0] == 0]
# Outputs: [(0, [(1, 0), (2, 0), (3, 0)]), (0, [(8, 0), (9, 0)]), (0, [(13, 0)]), (0, [(15, 0), (16, 0)])]

Conditional in the list comprehension:列表理解中的条件:

(p := (x, list(y)))[0] # is a check for x == 0 

Need to capture the right terms in p需要在 p 中捕获正确的术语

First p[1] for instance is:例如,第一个 p[1] 是:

[(1, 0), (2, 0), (3, 0)]   

We want the (1, 3) which index 0 of the first and last term of the list我们想要 (1, 3) 列表的第一项和最后一项的索引 0

p[1][0][0]   # index zero of first tuple -> 1
p[1][-1][0]  # index zero of last tuple  -> 3

So in general we have the tuple:所以一般来说,我们有元组:

(p[1][0][0], p[1][-1][0])
list = [1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1]

indexes_counts = []
start_zero_index = -1
is_inside_zero_sequence = False
zero_length = 0
# Use enumerate to loop on the lists and indexes
for i, x in enumerate(list):
    # If inside a zeroes sequence
    if is_inside_zero_sequence:
        # If current item is zero too
        if 0 == x:
            # Increase the zro_length counter
            zero_length += 1
        # Else, current element is not zero
        else:             
            # Handle end of zeroes sequence
            indexes_counts.append([start_zero_index, zero_length])
            is_inside_zero_sequence = False
            zero_length = 0
    # If not in zeroes sequence and current number is not zero
    elif 0 == x:
            # Handle not zero
            is_inside_zero_sequence = True
            start_zero_index = i
            zero_length = 1

# [[1, 3], [8, 2], [13, 1], [15, 2]]
print(indexes_counts)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM