How to find sorted 'means of indexes' of two lists?

Question:

The task I have is as shown. Given two lists of ints, such as:

lst1 = [4,1,3,5,2]
lst2 = [1,3,5,2,4]

I want to get the mean of the ints indexes. For example, the int 4 will have indexes of 0 and 3, thus will have an index mean of 1.5. Similarly, int 1 will have an index mean of 1. I want to then have all ints in a list, sorted by their ‘index mean’. The result should be:

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

as their means are 0.5, 1.5, 2, 2.5, and 3.5, respectively.

What is a fast pythonic way of doing this without going through some complicated iterations? All help is appreciated!

Asked By: You_Donut

||

Answers:

>>> lst1 = [4,1,3,5,2]
>>> lst2 = [1,3,5,2,4]
>>> sorted(lst1, key=lambda n: lst1.index(n) + lst2.index(n))
[1, 3, 4, 5, 2]

Note that finding the actual average (i.e. dividing the sum by 2) isn’t necessary since you’re using the values as sort keys; as long as they have the same comparison results as the averages (which they will since each sum is the average times a constant factor of 2) you get the correct result.

For a more efficient solution, you’d build a dictionary so you only need to iterate through each list once to sum up all the indices:

>>> avg_indices = {n: 0 for n in lst1}
>>> for a in (lst1, lst2):
...     for i, n in enumerate(a):
...         avg_indices[n] += i
...
>>> sorted(lst1, key=avg_indices.get)
[1, 3, 4, 5, 2]

Building lists of indices (and taking the actual average) would become necessary if you didn’t have the same number of occurrences of each item across the lists.

Answered By: Samwise

So there are probably multiple ways, and it all depends on the lists you are working on. Here are two examples:

lst1 = [4,1,3,5,2]
lst2 = [1,3,5,2,4]
means = []
for i in range(len(lst1)):
    i2 = lst2.index(lst1[i])    
    means.append(math.round((i+i2)/2))
print(means)

Another way is to use a generator function:

def indexmeans(a,b):
    for i in range(len(a)):
        i2 = b.index(a[i])
        yield math.round((i+i2)/2)

lst1 = [4,1,3,5,2]
lst2 = [1,3,5,2,4]

print(list(indexmeans(lst1, lst2)))

If you want to support lists with mismatched number of elements, handle if one value is not part of the other list and so on, you have to add the logic to handle that to suit your application.

Answered By: Espen