Compare two nested lists and keep the union of elements

Viewed 81

The title may be misleading. I will try to explain as clear as possible. I have two set of lists :

a = [
      [(1.5, 13), (1.5, 16)], #first list
      [(5.4, 100.5), (5.3, 100.5)] #second list
    ]

b = [
     [(1, 2), (1.5, 3)], #first list
     [(5.4, 100.5), (5.3, 100.5)] #second list
    ]

I would like to compare first list of a with first list of b and so on. Remove duplicates if I found any. The final outcome will look like this :

c = [
     [(1.5, 13), (1.5, 16), (1, 2), (1.5, 3)], #first list
     [(5.4, 100.5), (5.3, 100.5) ] #second list
    ]

As you can see, a and b will eventually append forming c. However, duplicates will not be appended as shown in second list of c. Position is not mutable.

How can I achieve this efficiently?

1 Answers

Use zip to zip the two lists together, and set to remove duplicates from the concatenated pairs:

[list(set(x + y)) for x, y in zip(a, b)]
# [[(1.5, 16), (1, 2), (1.5, 13), (1.5, 3)], [(5.4, 100.5), (5.3, 100.5)]]

If you want to maintain order(sets are unordered), use a dict and get the keys with dict.fromkeys(assuming Python 3.6+ for ordered dictionaries):

[list(dict.fromkeys(x + y)) for x, y in zip(a, b)]
# [[(1.5, 13), (1.5, 16), (1, 2), (1.5, 3)], [(5.4, 100.5), (5.3, 100.5)]]

For lower versions of python(dictionaries are unordered), you will need to use a collections.OrderedDict:

from collections import OrderedDict

[list(OrderedDict.fromkeys(x + y)) for x, y in zip(a, b)]
# [[(1.5, 13), (1.5, 16), (1, 2), (1.5, 3)], [(5.4, 100.5), (5.3, 100.5)]]

If you want the tuples to be sorted by the first element, use sorted:

[sorted(set(x + y)) for x, y in zip(a, b)]
# [[(1, 2), (1.5, 3), (1.5, 13), (1.5, 16)], [(5.3, 100.5), (5.4, 100.5)]]
Related