0

Say I have a list of lists like so:

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

I want to get the indices of the inner lists that contain unique elements. For the example above, the lists at index 2 is the only one that contains 7 and the list at index 3 is the only one that contains 6.

How would one go about implementing this in python?

doddy
  • 579
  • 5
  • 18
  • 1
    I'd probably use Counter and sets for this task. – PM 2Ring Nov 11 '17 at 14:39
  • @cᴏʟᴅsᴘᴇᴇᴅ I'm not too sure what to try here. My first instinct is to loop through and store all the numbers I find in an array at the corresponding index, since they are all integers and then if I try to insert at an already full index again, I know I have a repeat. While I know how to do this, I don't know how this will return the indices for the lists I need. – doddy Nov 11 '17 at 14:44
  • if len(set(x)) <> len(x), then x has duplicate elements - with x being one element of list. – Pierre G. Nov 11 '17 at 14:44

3 Answers3

4

Here's a solution using Counter. Each inner list is checked for a value that only has a single count, and then the corresponding index is printed (a la enumerate).

from collections import Counter
from itertools import chain

c = Counter(chain.from_iterable(l))
idx = [i for i, x in enumerate(l) if any(c[y] == 1 for y in x)] 

print(idx)
[0, 2, 3]

A possible optimisation might include precomputing unique elements in a set to replace the any call with a set.intersection.

c = Counter(chain.from_iterable(l))
u = {k for k in c if c[k] == 1}

idx = [i for i, x in enumerate(l) if u.intersection(x)]
cs95
  • 379,657
  • 97
  • 704
  • 746
  • Thank you. This works well. I apologize if this is is a terrible question but could you point me to some resources or documentation where I could learn about expressions such as idx = [i for i, x.....] I've seen solutions of this form before but I can't wrap my head around what is going on here specially with the comma. Is it saying something similar to: i,x = enumerate(l) for k in i: .... Or am I misunderstanding the expression. – doddy Nov 11 '17 at 14:48
  • @doddy The most obvious hit is https://stackoverflow.com/questions/34835951/what-does-list-comprehension-mean-how-does-it-work-and-how-can-i-use-it ... for general tutorials, see here: https://sopython.com/wiki/What_tutorial_should_I_read%3F – cs95 Nov 11 '17 at 14:50
  • Thank you. I apologize, I'm a beginner and really appreciate the help. – doddy Nov 11 '17 at 14:51
1

A naive solution:

>>> from collections import Counter
>>> from itertools import chain
>>> my_list = [[1,2,3,4],[4,5,3,2],[7,8,9,2],[5,6,8,9]]
# find out the counts.
>>> counter = Counter(chain(*my_list))
# find the unique numbers
>>> uniques = [element for element,count in counter.items() if count==1]
# find the index of those unique numbers
>>> result = [indx for indx,elements in enumerate(my_list) for e in uniques if e in elements]
>>> result
[0, 2, 3]
mshsayem
  • 17,557
  • 11
  • 61
  • 69
0

using itertools.chain with set.difference(set)

from itertools import chain
l = [[1,2,3,4],[4,5,3,2],[7,8,9,2],[5,6,8,9]]
[i for i in range(len(l)) if set(l[i]).difference(set(chain(*[j for j in l if j!=l[i]])))]
#[0, 2, 3]
Transhuman
  • 3,527
  • 1
  • 9
  • 15