Эффективный способ группировки индексов одинаковых элементов в списке Python - PullRequest
1 голос
/ 18 июня 2019

Допустим, у меня есть список, который выглядит следующим образом:

[1, 2, 2, 5, 8, 3, 3, 9, 0, 1]

Теперь я хочу сгруппировать индексы тех же элементов, поэтому результат должен выглядеть следующим образом:

[[0, 9], [1, 2], [3], [4], [5, 6], [7], [8]]

Как мне сделать это эффективным способом?Я стараюсь избегать использования циклов, поэтому любые реализации, использующие функции numpy / pandas, хороши.

Ответы [ 4 ]

3 голосов
/ 18 июня 2019

Используя панд GroupBy.apply, это довольно просто - используйте ваши данные для группировки по Серии индексов.Приятным бонусом здесь является поддержание порядка ваших индексов.

data = [1, 2, 2, 5, 8, 3, 3, 9, 0, 1]
pd.Series(range(len(data))).groupby(data, sort=False).apply(list).tolist()
# [[0, 9], [1, 2], [3], [4], [5, 6], [7], [8]]
3 голосов
/ 18 июня 2019

Вы можете использовать collections.defaultdict для группировки индексов:

from collections import defaultdict

lst = [1, 2, 2, 5, 8, 3, 3, 9, 0, 1]

d = defaultdict(list)
for i, x in enumerate(lst):
    d[x].append(i)

print(list(d.values()))
# [[0, 9], [1, 2], [3], [4], [5, 6], [7], [8]]

, которая также поддерживает порядок добавления индексов без сортировки.

0 голосов
/ 18 июня 2019

Не уверен, почему вы хотите "избегать циклов", поскольку нет никакого способа узнать, что вызываемые вами функции в любом случае не используют циклы, добавляя накладные расходы при вызове функции.

Кроме того, после группировки вы теряете информацию о том, что она группирует, поэтому представляется целесообразным поместить вывод в dict.

Это делает это:

from itertools import groupby

l = [1, 2, 2, 5, 8, 3, 3, 9, 0, 1]
result = {
    key: [item[0] for item in group]
    for key, group in groupby(sorted(enumerate(l), key=lambda x: x[1]), lambda x: x[1])
}

print(result)

Выход:

{0: [8], 1: [0, 9], 2: [1, 2], 3: [5, 6], 5: [3], 8: [4], 9: [7]}
0 голосов
/ 18 июня 2019

Это решение является модификацией подсчета хешей, но вместо подсчета просто сохраните индекс найденного значения.

arr = [1,2,2,5,8,3,3,9,0,1]
d = dict()  
for i,v in enumerate(arr):  
    d[v] = d.get(v,[]) #use an if-statement to avoid doing this too often
    d[v].append(i) 
print(d.values()) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...