How to get index of neighboring repeating elements within a Python list?

Viewed 124

What is a fast way to get index of only neighboring repeating elements within a Python list?

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

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

A set will be very handy to avoid having duplicates, and once you have the indices you can covert it back to a list and sort it, so try the following:

# 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))

You can use itertools.groupby to handle the grouping of neighbouring repeated elements:

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]

easy in pandas

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

output:

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

Here's an O(n) solution. Based upon @lmiguelvargasf 's answer.

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

Your result will be sorted. Pretty sure this is as quick as it gets :D. Not as short and clean but definitely fast.

After figuring out for a while, I came out with a fast way using numpy without using slower nested for loops:

(Improving solution thanks to answer below from @lmiguelvargasf)

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]
Related