3

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!

jpp
  • 159,742
  • 34
  • 281
  • 339
mb567
  • 691
  • 6
  • 21

1 Answers1

5

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.

jpp
  • 159,742
  • 34
  • 281
  • 339
  • 1
    I had started writing a solution using `combination` and `enumerate` and all that jazz ... But this is so much more straightforward. A bit more explanation for novices is welcome though. Basically, create a dictionary with the unique values from `a` mapped to the values from `b` put in a list. Then you can just `list()` the keys of that dictionary and get their `min()` values. – Bram Vanroy Oct 29 '18 at 14:56
  • @BramVanroy, Sure, I've tried to add a bit more explanation. – jpp Oct 29 '18 at 15:11
  • 1
    Great! Very helpful for everyone. +1 – Bram Vanroy Oct 29 '18 at 15:12