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