How can I get unique arrays in Python?

Question:

I got a fairly large array of arrays of length 2 (List[List[int, int]])
How can I unique arrays of them? Preferably without using different libraries

I’ve seen several solutions that use numpy, but I’m unlikely to be able to use this in olympiads

# Example input:
nums = [[2, 9], [3, 6], [9, 2], [6, 3]]

for i in nums:
    # some code here

# Output:
# nums = [[2, 9], [3, 6]]

I tried doing this but I guess it’s not a very fast solution

# Example input:
nums = [[2, 9], [3, 6], [9, 2], [6, 3]]

unique = []
for i in nums:
    if sorted(i) not in unique:
        unique.append(sorted(i))

# Output:
print(unique) # [[2, 9], [3, 6]]

Asked By: ClayMix

||

Answers:

This answer is wrong. The set constructor does not sort its elements.

As @Swifty mentioned, you can use set to solve this problem. Send each pair through the set constructor to sort the pair, then convert it to tuple to make it hashable and use set again to remove duplicate tuples.

nums = [[2, 9], [3, 6], [9, 2], [6, 3]]

num_tuples = set(tuple(set(pair)) for pair in nums)

print(num_tuples)  # {(9, 2), (3, 6)}

Warning: As pointed out by @Samwise

This is a little dodgy because you’re assuming that tuple(set(pair)) will deterministically create the same tuple ordering for any given set. This is probably true in practice (IIRC when you iterate over a set the items always come out in hash order, at least in CPython 3) but I’m not sure it’s necessarily guaranteed by the Python spec. –

Answered By: Fractalism

Turn each pair into a sorted tuple, put them all into a set, then turn that back into a list of lists.

>>> nums = [[2, 9], [3, 6], [9, 2], [6, 3]]
>>> {tuple(sorted(n)) for n in nums}
{(2, 9), (3, 6)}
>>> [list(t) for t in {tuple(sorted(n)) for n in nums}]
[[2, 9], [3, 6]]

The tuple is necessary because a set (which is created via the {} set comprehension expression) needs to contain hashable (immutable) objects.

Answered By: Samwise

To deal with sets not being hashable, you can create a set of frozensets this way:

unique = {frozenset(i) for i in nums}

Then you can use whichever means to turn the results into the objects you want; for example:

unique = [list(i) for i in unique]
Answered By: Swifty
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.