Извлечь индекс не повторяющихся элементов в списке Python - PullRequest
0 голосов
/ 01 сентября 2018

У меня есть список:

input = ['a','b','c','a','b','d','e','d','g','g']

Я хочу индекс всех элементов, кроме дубликата в списке.

output = [0,1,2,5,6,8]

Ответы [ 6 ]

0 голосов
/ 01 сентября 2018

Еще одна версия, использующая побочный эффект в понимании списка.

>>> xs=['a','b','c','a','b','d','e','d','g','g']
>>> seen = set()
>>> [i for i, v in enumerate(xs) if v not in seen and not seen.add(v)]
[0, 1, 2, 5, 6, 8]

Понимание списка фильтрует индексы значений, которые еще не были замечены. Хитрость в том, что not seen.add(v) всегда верно, потому что seen.add(v) возвращает None. Из-за оценки короткого замыкания seen.add(v) выполняется тогда и только тогда, когда v не видно, добавляя новые значения к seen на лету.

В конце, visible содержит все значения списка ввода.

>>> seen
{'a', 'c', 'g', 'b', 'd', 'e'}

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

0 голосов
/ 01 сентября 2018

В этом вопросе отсутствует решение pandas. ?

>>> import pandas as pd
>>> inp = ['a','b','c','a','b','d','e','d','g','g']
>>> 
>>> pd.DataFrame(list(enumerate(inp))).groupby(1).first()[0].tolist()
[0, 1, 2, 5, 6, 8]
0 голосов
/ 01 сентября 2018

Это однострочник, использующий zip и reversed

>>> input = ['a','b','c','a','b','d','e','d','g','g']
>>> sorted(dict(zip(reversed(input), range(len(input)-1, -1, -1))).values())
[0, 1, 2, 5, 6, 8]
0 голосов
/ 01 сентября 2018

Если вы не возражаете против индексов последних появлений дубликатов и используете Python 3.6+, вот альтернативное решение:

list(dict(map(reversed, enumerate(input))).values())

Возвращает:

[3, 4, 2, 7, 6, 9]
0 голосов
/ 01 сентября 2018

Вы можете сделать что-то вроде этого, проверяя счетчик (хотя это требует больших вычислений):

indexes = []
for i, x in enumerate(inputlist):
    if (inputlist.count(x) == 1
        and x not in inputlist[:i]):
        indexes.append(i)

Это проверяет следующее:

  1. если предмет появляется только один раз. Если это так, продолжайте ...
  2. , если элемент не отображался в списке до сих пор. Если это так, добавьте в список результатов
0 голосов
/ 01 сентября 2018

Вы должны перебрать перечисленный список и добавить каждый элемент к набору "видимых" элементов и добавить индекс в выходной список , если элемент еще не был просмотрен (отсутствует в «увиденный» набор).

О, имя input переопределяет встроенную функцию input(), поэтому я переименовал ее input_list.

output = []
seen = set()
for i,e in enumerate(input_list):
    if e not in seen:
        output.append(i)
        seen.add(e)

, что дает output как [0, 1, 2, 5, 6, 8].


зачем использовать набор?

Вы можете подумать, зачем использовать набор, если вы можете сделать что-то вроде:

[i for i,e in enumerate(input_list) if input_list.index(e) == i]

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

Однако это не так эффективно, как использование набора, потому что list.index требует, чтобы Python перебирал список, пока не найдет элемент (или не найдет). Эта операция сложна на O(n), и поскольку мы вызываем ее для каждого элемента в input_list, полное решение будет O(n^2).

С другой стороны, использование набора, как в первом решении, дает решение O(n), потому что проверка, является ли элемент in, является сложностью O(1) (средний случай). Это связано с тем, как наборы реализованы (они похожи на списки, но каждый элемент хранится по индексу его хеша, так что вы можете просто вычислить хеш элемента и посмотреть, есть ли там элемент для проверки членства, а не для перебора заметьте, что это смутное упрощение, но это их идея).

Таким образом, поскольку каждая проверка на членство равна O(1), и мы делаем это для каждого элемента, мы получаем решение O(n), которое намного лучше, чем O(n^2) решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...