Choose smallest value from lists given same coordinates in 2d list

Viewed 101

I have two lists:

a = [[9, 5], [9, 10000], [9, 10000], [5, 10000], [5, 10000], [10001, 10], [10001, 10]]
b = [19144.85, 8824.73, 26243.88, 23348.02, 40767.17, 55613.43, 40188.8]

I am trying to remove the repeated coordinates in a and remove the adjacent value in b but by leaving the smallest value. So for example coordinate [9,10000] is repeated twice with values in b of 8824.73 and 26243.88 the result should be two lists where there is only one [9,10000] with the smaller of b which is 8824.73.

So overall the result should look like:

aa = [[9,5],[9,10000],[5,10000],[10001,10]]
bb = [19144.85, 8824.73, 23348.02, 40188.8]

I am finding it difficult to formulate the problem and iterate through the lists and I am not sure how I can use the zip function. Any help is appreciated!

1 Answers

Here is an O(n) solution using collections.defaultdict:

from collections import defaultdict

dd = defaultdict(list)

for (key1, key2), value in zip(a, b):
    dd[(key1, key2)].append(value)

aa = list(map(list, dd))
bb = list(map(min, dd.values()))

print(aa, bb, sep='\n'*2)

[[9, 5], [9, 10000], [5, 10000], [10001, 10]]

[19144.85, 8824.73, 23348.02, 40188.8]

Explanation

There are 3 steps:

  1. Create a dictionary mapping each pair of keys to a list of values. Be careful to use tuple as keys, which must be hashable.
  2. For unique keys, just extract your defaultdict keys, mapping to list so that you have a list of lists instead of list of tuples.
  3. For minimum values, use map with min.

Note on ordering

Dictionaries are insertion ordered in Python 3.6+, and this can be relied upon in 3.7+. In earlier versions, you can rely on consistency of ordering between dd.keys and dd.values provided no operations have taken place in between access of keys and values.

Related