You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python:寻找含NaN列表中相邻重复值的起始索引(无for循环)

不使用for循环找出列表中相邻重复值的起始索引

给定输入列表 [NaN, NaN, 1, 2, NaN, 2, 2, 2, 4],我们需要找出每组相邻重复值的起始索引,期望输出为 [0, 2, 3, 4, 5, 8]。你已经用for循环实现了正确逻辑,下面提供一种基于numpy向量化操作的无显式循环方案:

无循环实现代码

import numpy as np

input_list = [np.nan, np.nan, 1, 2, np.nan, 2, 2, 2, 4]
arr = np.array(input_list)

# 生成相邻元素是否属于不同组的布尔数组,单独处理NaN的特殊情况
# 由于NaN与自身比较结果为False,需额外判断相邻是否均为NaN
not_same_group = np.logical_or(
    arr[1:] != arr[:-1],
    np.logical_and(np.isnan(arr[1:]), np.isnan(arr[:-1]))
)

# 第一个元素必然是一组的起始,在布尔数组开头补True
mask = np.concatenate([[True], not_same_group])

# 提取所有标记为起始位置的索引
start_adj_i = np.where(mask)[0].tolist()

print(start_adj_i)  # 输出: [0, 2, 3, 4, 5, 8]

代码说明

  • 将输入列表转为numpy数组,利用向量化运算替代显式循环
  • not_same_group数组标记从第二个元素开始,当前元素与前一个是否属于不同重复组:
    • 非NaN值直接通过arr[1:] != arr[:-1]判断
    • NaN需额外判断相邻是否均为NaN,这种情况属于同一组,不标记为不同
  • 在数组开头补True,因为第一个元素肯定是一组的起始
  • 用np.where提取所有起始位置的索引,转成列表即为结果

原循环实现对比

你原有的for循环逻辑正确,核心是跟踪前一个值,判断当前值是否属于新的重复组:

import numpy as np

start_adj_i = []
prev_val = -999  # 一个不可能出现在列表中的值
for i, x in enumerate(input_list):
    if np.isnan(x) and np.isnan(prev_val):
        continue
    elif x != prev_val:
        start_adj_i.append(i)
    prev_val = x  # 更新前一个值用于下一次迭代

print(start_adj_i)  # 输出: [0, 2, 3, 4, 5, 8]

内容的提问来源于stack exchange,提问作者nk123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 08:07:09