Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare elements of a list of lists and return a list

Tags:

python

list

I have a list of lists, I don't know the length of the main list but each 'sublist' contains necessarily 6 floats. I need to compare each float of each sublist and keep the smaller one for the first three floats and the higher one for the last three and finally, I need to return all these values in a 6-float list in the same order.

Here is an example:

list1 = [[-2.0, 0.0, -2.0, 2.0, 10.0, 2.0], [-1.0, 0.0, 2.0, 1.0, 5.0, 4.0]]
# Compare list1[0][0] with list1[1][0]
# Will return -2.0 (because the index is between 0 and 2 so it returns the lower float)
# Compare list1[0][4] with list1[1][4]
# Will return 10.0 (because the index is between 3 and 5 so it returns the higher float)
# The final result which should be returned is:
# [-2.0, 0.0, -2.0, 2.0, 10.0, 4.0]

list2 = [[-2.0, 0.0, -2.0, 2.0, 10.0, 2.0], [-1.0, 0.0, 2.0, 1.0, 5.0, 4.0], [3.0, 0.0, -1.0, 4.0, 1.0, 0.0]]
# Compare list2[0][2] with list2[1][2] with list2[2][2]
# Will return -2.0 (because the index is between 0 and 2 so it returns the lower float)
# The final result which should be returned is:
# [-2.0, 0.0, -2.0, 4.0, 10.0, 4.0]

I read about zip(), sets, list comprehension and different topics on this site but I couldn't achieve what I want.

like image 636
UKDP Avatar asked Mar 13 '23 12:03

UKDP


2 Answers

You can do it "manually" using 2 nested for loops

list1 = [[-2.0, 0.0, -2.0, 2.0, 10.0, 2.0], [-1.0, 0.0, 2.0, 1.0, 5.0, 4.0]]
output = [0 for x in range(6)]
# iterate over the 6 numbers
for i in range(6):
    value = list1[0][i] # pick the first number
    #iterate over all the lists, if we find a bigger/smaller one our current one then save it
    for j in range(len(list1)):
        if i >= 3 and list1[j][i] > value:
                value = list1[j][i]
        elif i < 3 and list1[j][i] < value:
                value = list1[j][i]
    #put the biggest/smallest value in the correct place in the output array
    output[i] = value
print output
like image 32
user3088440 Avatar answered Mar 16 '23 01:03

user3088440


If you do zip(*list2), you'll create a list of the first element of each sublist together, the second elements together, etc. So you want to get the minimum value of the first 3 and the maximum value of the next 3.

zipped = zip(*list2)
result = [min(zipped[i]) for i in range(3)] + [max(zipped[i]) for i in range(3, 6)]

In Python 3 zip() will fetch the zipped sublists lazily like an iterator, while in Python 2 it will create the whole list in advance. This is similar to range() between the two version. If you want a lazy generation in Python 2, you can use the iterator version from the itertools module.

import itertools

zipped = itertools.izip(*list2)
result = [min(zipped.next()) for _ in range(3)] + [max(zipped.next()) for _ in range(3)]

Edit: Visual example of what zip() achieves.

>>> a = [[1, 2, 3], [4, 5, 6]]
>>> zip(*a) # you need `list(zip(*a))` in Python 3
[(1, 4), (2, 5), (3, 6)]

The star syntax unpacks the list in several arguments, so that zip(*[[1, 2, 3], [4, 5, 6]]) becomes zip([1, 2, 3], [4, 5, 6]), which is what you want.

like image 183
Reti43 Avatar answered Mar 16 '23 02:03

Reti43