Python实现数组元素后续连续匹配指定值时返回对应布尔结果
问题说明
需要识别数组中满足「当前元素为指定值,且后续紧随指定数量的同值元素」的元素位置。以测试场景为例,需要定位B元素后紧随2个额外B(即从当前位置开始连续3个元素均为B)的位置,给定测试数组与预期结果如下:
arr = ['a', 'a', 'B', 'B', 'B', 'a'] # 预期输出 desired_result == [False, False, True, False, False, False]
使用itertools.groupby()的常规方案无法满足需求:该方案会将连续匹配段内的所有位置统一标记,不会区分匹配值出现在当前元素之前还是之后,运行得到的结果不符合预期:
from itertools import groupby groupby_result = [] for k, g in groupby(arr): len_ = len(list(g)) groupby_result += [len_ >= 3 and k == "B"] * len_ # 错误输出 [False, False, True, True, True, False] groupby_result == [False, False, True, True, True, False]
实现方法
方法1:直接遍历判断(无依赖,易扩展)
核心逻辑是逐位检查当前索引开始的连续指定长度区间内,是否全为目标值,提前规避索引越界问题即可:
arr = ['a', 'a', 'B', 'B', 'B', 'a'] target_val = "B" # 要求的连续匹配总长度:当前元素+后续2个同值,总长度为3 match_length = 3 arr_len = len(arr) result = [] for idx in range(arr_len): # 剩余元素长度不足要求的匹配长度,直接标记False if idx + match_length > arr_len: result.append(False) continue # 检查从当前位开始的match_length个元素是否全为目标值 is_match = True for offset in range(match_length): if arr[idx + offset] != target_val: is_match = False break result.append(is_match)
运行后result的值为[False, False, True, False, False, False],完全符合预期。如果需要调整匹配规则,比如找后面跟3个同值的起始位置,只需要把match_length改成4即可。
方法2:调整groupby标记逻辑
如果要沿用groupby的思路,只需要修改连续段的标记规则:当连续段是目标值、且段长度大于等于要求的匹配长度时,仅给段的第一个位置标记True,段内其余位置全部标记False即可:
from itertools import groupby arr = ['a', 'a', 'B', 'B', 'B', 'a'] target_val = "B" match_length = 3 result = [] for key, group in groupby(arr): seg_length = len(list(group)) if key == target_val and seg_length >= match_length: # 段首为匹配位置,其余位置不匹配 result += [True] + [False] * (seg_length - 1) else: result += [False] * seg_length
该方法同样可以得到正确结果,适合已经在使用itertools工具链的编码场景。
内容的提问来源于stack exchange,提问作者i_failed_the_turing_test
相关产品推荐
相关产品推荐

