У меня есть следующий список слов:
x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga','Lam']
Мне нужно удалить слова, которые появляются только один раз, и вернуть туда индексы или позиции.
y = ['Gaga', 'Gaga', 'Lam', 'Gaga', 'Lam']
loc = [0, 0, 0, 1, 1, 0, 0]
Любая простая функция для этого?






Вы можете использовать collections.Counter и изолировать элементы, появляющиеся только один раз. затем используйте списки для желаемых результатов. Общее решение - O (n), хотя оно включает в себя 3 прохода.
x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga','Lam']
from collections import Counter
singles = {k for k, v in Counter(x).items() if v == 1}
y = [i for i in x if i not in singles]
loc = [int(i in singles) for i in x]
print(y, loc, sep='\n')
['Gaga', 'Gaga', 'Lam', 'Gaga', 'Lam']
[0, 0, 0, 1, 1, 0, 0]
Вы можете использовать класс Counter именно для этой цели:
from collections import Counter
x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga','Lam']
c = Counter(x)
new_values = [item for item in x if c[item] > 1]
indexes = [1 if c[item] == 1 else 0 for item in x]
print(new_values)
print(indexes)
Выход:
['Gaga', 'Gaga', 'Lam', 'Gaga', 'Lam']
[0, 0, 0, 1, 1, 0, 0]
Отметим, что O (n) тоже. Но не большой поклонник тройного против int(c['item'] == 1). Кроме того, он менее эффективен, чем мой, поскольку вы тестируете c[item] == 1 в обоих списках.
Альтернативный вариант один лайнер с модулем pandas и его функцией pd.Series.duplicated():
In [80]: x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga','Lam']
In [81]: (~pd.Series(x).duplicated(keep=False)).astype(int).tolist()
Out[81]: [0, 0, 0, 1, 1, 0, 0]
Чтобы удалить все недубликаты:
In [85]: s = pd.Series(x)
In [86]: s[s.duplicated(keep=False)].tolist()
Out[86]: ['Gaga', 'Gaga', 'Lam', 'Gaga', 'Lam']
Второстепенный момент, даже лучше было бы вычислить s.duplicated(keep=False) в качестве начального шага и использовать его в обоих своих расчетах. Но все же +1 за хорошее решение Panda.
@jpp, конечно, при объединении этих двух в один общий блок, s = pd.Series(x) и dups = s.duplicated(keep=False) должны быть рассчитаны заранее. Я разделил их для демонстрации однострочников pandas
Не могли бы вы создать новый список и поработать с ним?
x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga','Lam']
loc = []
new_x = []
for name in x:
if x.count(name) == 1:
loc.append(1)
else:
loc.append(0)
new_x.append(name)
Вы также можете использовать понимание списка
x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga', 'Lam']
y = [name for name in x if x.count(name) != 1]
[«Гага», «Гага», «Лам», «Гага», «Лам»]
это решение имеет квадратичную сложность по количеству элементов списка, что не является лучшим
Вы что-нибудь пробовали?