1

What is the most efficient way to find the indexes of strings in a list that occur only once?

foo = ['it', 'does', 'it', 'very', 'very', 'well']
bar = ???  # bar = [1, 5]

I already know about sets, dictionaries and list comprehensions. The problem I'm trying to solve here is in my production code I have parallel data lists where the index of one is the index of many which can't be changed for historical reasons.

empty
  • 5,194
  • 3
  • 32
  • 58
  • Why the close votes as "too broad"? I thought it was well-targeted question that currently has only one good answer. – empty Sep 29 '17 at 15:54

4 Answers4

3

With collections.Counter subclass:

import collections

foo = ['it', 'does', 'it', 'very', 'very', 'well']
counts = collections.Counter(foo)
result = [i for i,v in enumerate(foo) if counts[v] == 1]

print(result)

The output:

[1, 5]
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
0

You will get what you want. Dictionaries are faster in python

from collections import Counter
foo = ['it', 'does', 'it', 'very', 'very', 'well']
d = dict(Counter(foo))
[i for i,v in enumerate(foo) if counts[v]  == 1]

You can also use set(foo)

0

You can try something like this, especially if the size of your foo list is bigger than in your example above and have lots of duplicates.

seen = set()
[i for i,e in enumerate(foo) if not (e in seen or seen.add(e) or e in foo[i+1:])]
Bruno Astrolino
  • 401
  • 5
  • 3
-2

It depends on the kind of efficiency you would like to get. You could do this directly in a list comprehension, straightforward and readable:

bar = [index for index,el in enumerate(foo) if foo.count(el)==1]

Please see this for info if you would like to use Counter

jabargas
  • 210
  • 1
  • 3