簡體   English   中英

給定兩個相同長度的二進制列表,如何找到與交替列表相對應的所有索引對,而兩者之間沒有索引?

[英]Given two binary lists of same length, how to find all the pair of indices corresponding to ones of alternating lists without ones in between?

假設您有兩個長度相同的列表 L1 和 L2,每個列表只有 0 和 1 個值。 如何有效地找到所有索引對[i, j]使得:

  1. i < j
  2. L1[i] == 1 and L2[j] == 1
  3. 對於任何k使得i < k < j我們有L1[k] == 0 and L2[k] == 0

例子:

L1 = [1,0,0,0,1,0,0,1,0]
L2 = [0,0,1,0,0,1,0,0,1]

預期 output:

[[0, 2], [4, 5], [7, 8]]

我的以下代碼有效,但對於大型計算來說非常慢。 我正在尋找一個更快的解決方案。

import math

def getNext(ind,i):
    nextList = [idx for idx,x in enumerate(ind) if (x and idx>i)]
    if nextList:
        return min(nextList)
    else:
        return math.inf
    
def getPrevious(ind,i):
    previousList = [idx for idx,x in enumerate(ind) if (x and idx<i)]
    if previousList:
        return max(previousList)
    else:
        return -math.inf

def getIndices(list1,list2):
    indices = [[i,j] for i,x in enumerate(list1) 
                     for j,y in enumerate(list2)
                     if x and y and i<j and getNext(list1,i,'true') >= j
                        and getPrevious(list2,j,'true') <= i
              ] 
    return indices

您可以在進行單次迭代時跟蹤引用第一個列表中的 1 的i 當您在隨后的下一次迭代中遇到另一個列表中的 1 時,您有一個 output 的元組。 每當您遇到這樣的問題時,請忘記i (將其設置為 -1 或其他無效索引或無)並繼續:

def find_pairs(lst1, lst2):
    i = -1
    for j, (a, b) in enumerate(zip(lst1, lst2)):
        if b and i != -1: # End of a range
            yield i, j
            i = -1  # Invalidate starting index of range
        if a:  # Start a new range
            i = j

示例調用的輸入比您在問題中發布的要少:

lst1 = [1,1,0,1,1,1,0,0,1,0,1,0]
lst2 = [0,0,0,1,1,0,0,1,0,0,1,1]
print(list(find_pairs(lst1, lst2)))    

Output:

[(1, 3), (3, 4), (5, 7), (8, 10), (10, 11)]

您可以嘗試使用生成器的版本:

L1 = [1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0]
L2 = [0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1]


from itertools import count


def get_pairs(L1, L2):
    c = count(1)
    L2, L1 = zip(
        *[
            (next(c) if i == 1 else 0, next(c) if j == 1 else 0)
            for i, j in zip(L2, L1)
        ]
    )

    i1 = ((i, v) for i, v in enumerate(L1) if v != 0)
    i2 = ((i, v) for i, v in enumerate(L2) if v != 0)

    try:
        (idx1, v1), (idx2, v2) = next(i1), next(i2)
        while True:
            while v1 - v2 != -1:
                if idx1 < idx2:
                    idx1, v1 = next(i1)
                else:
                    idx2, v2 = next(i2)
            yield idx1, idx2
            idx1, v1 = next(i1)
    except StopIteration:
        pass


print(list(get_pairs(L1, L2)))

印刷:

[(1, 3), (3, 4), (5, 7), (8, 10), (10, 11)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM