【问题标题】:How to get index of neighboring repeating elements within a Python list?如何获取 Python 列表中相邻重复元素的索引?
【发布时间】:2020-10-31 19:32:00
【问题描述】:

有什么方法可以快速获取 Python 列表中相邻重复元素的索引?

# Have 
list1 = [2, 2, 2, 3, 5, 6, 6, 6]
#        0  1  2        5  6  7

# Want
index = [0, 1, 2, 5, 6, 7]

【问题讨论】:

  • 您的列表是否保证按升序排序?
  • 未专门排序,但以重复元素彼此相邻的方式排列

标签: python list indexing repeat


【解决方案1】:

您可以使用itertools.groupby来处理相邻重复元素的分组:

from itertools import groupby

list1 = [2, 2, 2, 3, 5, 6, 6, 6]

index, i = [], 0
for k, g in groupby(list1):
    grp = len(list(g))
    if grp > 1:
        index.extend(range(i, i+grp))
        i += grp
    else:
        i += 1
    
print(index)
# [0, 1, 2, 5, 6, 7]

【讨论】:

  • 注意:你可以简单地做index.extend(range(i, i+grp))
【解决方案2】:

经过一段时间的研究,我找到了一种使用 numpy 的快速方法,而无需使用较慢的嵌套 for 循环:

(感谢以下来自 @lmiuelvargasf 的回答,改进了解决方案)

dup_ix = [(i, i-1) for i in range(1, len(list1)) if list1[i] == list1[i-1]]
    
dup_ix = np.array(dup_ix).flatten() 
dup_ix = list(set(dup_ix))
    
print(dup_ix)
[0, 1, 2, 5, 6, 7]

【讨论】:

  • 嘿,如果您好奇,我已经发布了一个更快的解决方案 (O(n)),但很高兴看到您找到了适合您的解决方案!
  • 嘿@M Z,感谢您的评论。认为 last = False 可能不需要,因为 i 范围已经解决了这个问题?
  • 很确定您需要它或类似的东西,以管理一些边缘情况。
【解决方案3】:

这是O(n) 解决方案。基于@lmiuelvargasf 的回答。

list1 = [2, 2, 2, 3, 5, 6, 6, 6]
#        0  1  2        5  6  7

index = []

last = False
for i in range(1, len(list1)):
    if list1[i - 1] != list1[i]:
        last = False
    elif last:
        index.append(i)
        last = True
    else:
        index.append(i - 1)
        index.append(i)
        
        last = True

您的结果将被排序。很确定这是最快的:D。 没有那么短和干净,但绝对很快。

【讨论】:

    【解决方案4】:

    在熊猫中很容易

    import pandas as pd
    df = pd.DataFrame(list1)
    ids = df.index[(df[0].diff() == 0) | (df[0].diff(-1) == 0)].values
    

    输出:

    array([0, 1, 2, 5, 6, 7])
    

    【讨论】:

    • 你建议安装一个库只是为了解决这个问题......
    • 我不知道我认为使用世界上最流行的 pkg 之一发布解决方案可能对某些使用它的人有用
    【解决方案5】:

    一个集合将非常方便地避免重复,一旦你有了索引,你可以将它转换回一个列表并对其进行排序,所以尝试以下操作:

    # Have 
    list1 = [2, 2, 2, 3, 5, 6, 6, 6]
    #        0  1  2        5  6  7
    
    result = set()
    for i in range(1, len(list1)):
        if list1[i - 1] == list1[i]:
            result.add(i - 1)
            result.add(i)
    index = sorted(list(result))
    

    【讨论】:

    • 第二种效率如何? not in 操作和 inO(n) 计算每个!看看result的最后一个元素是否已经存在
    • @MZ,问题是在第一种方法中我使用sorted,它将采用基本情况O(n log(n))
    • O(n^2) 更糟。只需查看result 中的最后一个元素,您就会知道是否需要添加索引。
    猜你喜欢
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    相关资源
    最近更新 更多