71

I have a list of lists like this:

i = [[1, 2, 3], [2, 4, 5], [1, 2, 3], [2, 4, 5]]

I would like to get a list containing "unique" lists (based on their elements) like:

o = [[1, 2, 3], [2, 4, 5]]

I cannot use set() as there are non-hashable elements in the list. Instead, I am doing this:

o = []
for e in i:
  if e not in o:
    o.append(e)

Is there an easier way to do this?

Georgy
  • 12,464
  • 7
  • 65
  • 73
Phani
  • 3,267
  • 4
  • 25
  • 50
  • 1
    An unrelated question, but why is this possible in other languages like Java? – gchandra Mar 30 '21 at 06:47
  • I guess it is allowed because every object in Java implements its hashcode and equals method (via Java base Object class or overridden methods) and thus can be a key in a map. But even in Java, having mutable structures like Lists or Sets as keys would be a bad idea. See https://stackoverflow.com/a/9973694/5065946 – powersource97 Aug 04 '21 at 01:50

4 Answers4

111

You can create a set of tuples, a set of lists will not be possible because of non hashable elements as you mentioned.

>>> l = [[1, 2, 3], [2, 4, 5], [1, 2, 3], [2, 4, 5]]
>>> set(tuple(i) for i in l)
{(1, 2, 3), (2, 4, 5)}
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
7
i = [[1, 2, 3], [2, 4, 5], [1, 2, 3], [2, 4, 5]]

print([ele for ind, ele in enumerate(i) if ele not in i[:ind]])
[[1, 2, 3], [2, 4, 5]]

If you consider [2, 4, 5] to be equal to [2, 5, 4] then you will need to do further checks

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
6

You can convert each element to a tuple and then insert it in a set.

Here's some code with your example:

tmp = set()
a = [[1, 2, 3], [2, 4, 5], [1, 2, 3], [2, 4, 5]]
for i in a:
    tmp.add(tuple(i))

tmp will be like this:

{(1, 2, 3), (2, 4, 5)}
Alberto Coletta
  • 1,563
  • 2
  • 15
  • 24
1

Here's another way to do it:

I = [[1, 2, 3], [2, 4, 5], [1, 2, 3], [2, 4, 5]]
mySet = set()

for j in range(len(I)):
  mySet = mySet | set([tuple(I[j])])

print(mySet)
Malekai
  • 4,765
  • 5
  • 25
  • 60