Python Forum
sorting list of lists - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: sorting list of lists (/thread-25935.html)



sorting list of lists - pframe - Apr-16-2020

I have the following:

list_1=[[499, 943, 1447, 943], [356, 944, 1447, 944], [356, 1226, 1447, 1226], [357, 1228, 1446, 1228], [292, 1456, 1441, 1456], [293, 1457, 1440, 1457], [292, 1991, 1441, 1991], [292, 2096, 1440, 2096], [293, 2098, 1440, 2098]] 
The list is set out in [[x1,y1,x2,y2],......] format and it is based in ascending order based off y1 (it is mean't to go down the page). Every coordinate is mean't to represent a line when joined.

list_1 has 5 lines in total, where as the above list tells me there are 9. Not only that, 3 lines are individual lines and far apart where as 2 lines are near each other together.

So for example:

[499, 943, 1447, 943] & [356, 944, 1447, 944] = 1 line (approx coordinate could be = [356, 944, 1447, 944] )

[356, 1226, 1447, 1226]& [357, 1228, 1446, 1228]=1 line (approx coordinate could be =[356, 1226, 1447, 1226])

[292, 1456, 1441, 1456]& [293, 1457, 1440, 1457] =1 line (approx coordinate could be = [292, 1456, 1441, 1456])

[292, 1991, 1441, 1991] & **[292, 2096, 1440, 2096], [293, 2098, 1440, 2098]** = 2 lines (where the bold coordinates represent the same line) (approx coordinate could be = [292, 1991, 1441, 1991] and [292, 2096, 1440, 2096])
How do I write a function that automatically filters those coordinates and returns the right amount of lines i.e 5 and gives an approximation of where that line is.


RE: sorting list of lists - Larz60+ - Apr-16-2020

what have you tried?
show code working or not


RE: sorting list of lists - pframe - Apr-16-2020

from operator import itemgetter
import itertools

list_1=[[499, 943, 1447, 943], [356, 944, 1447, 944],
   [356, 1226, 1447, 1226], [357, 1228, 1446, 1228],
   [292, 1456, 1441, 1456], [293, 1457, 1440, 1457],
   [292, 1991, 1441, 1991],
   [292, 2096, 1440, 2096], [293, 2098, 1440, 2098]]

x1_value=list(map(itemgetter(0), a)) #sort out the x1 values
lowest_x=min(x1_value) #finds the lowest x1 value

#now i will replace all x1 value with the lowest so it is consistent x1
i=0
for i in range(0,len(a)):
    a[i][0]=lowest_x
    i+=1

#   [[292, 943, 1447, 943], [292, 944, 1447, 944],
    #[292, 1226, 1447, 1226], [292, 1228, 1446, 1228],
    #[292, 1456, 1441, 1456], [292, 1457, 1440, 1457],
    #[292, 1991, 1441, 1991], [292, 2096, 1440, 2096],
    #[292, 2098, 1440, 2098]]


y1=list( map(itemgetter(1), a )) #puts y1 in a list

# narrow downs your y1 value
index = 1
while index < len(y1):
    #print(f"comparing {y1[index-1]} with {y1[index]} y1 list {y1}")
    if abs(y1[index] - y1[index - 1]) < 4:
        del y1[index]
    else:
        index += 1


#print(a)
#print(y1)

#now i will check if my y1 list is in a. Where rr represent a and pp represent y 
rr = a
pp = [[y] ]
result = []
ignore = []

for item in itertools.chain.from_iterable(pp):
    for pair in rr:
        if item in pair:
            #print('Yepp, {} is in {}. Ignoring!'.format(item, pair))
            ignore.append(pair)
        elif not pair in result and pair not in ignore:
            result.append(pair)
print(a)
print('Result: {}'.format(ignore))

# [[292, 943, 1447, 943], [292, 1226, 1447, 1226], [292, 1456, 1441, 1456], [292, 1991, 1441, 1991], [292, 2096, 1440, 2096]]
As you can see it does the job, but is there a simple solution or a cleaner code that runs faster?


RE: sorting list of lists - Larz60+ - Apr-17-2020

how about:
list_1 = [
    [499, 943, 1447, 943],
    [356, 944, 1447, 944],
    [356, 1226, 1447, 1226],
    [357, 1228, 1446, 1228],
    [292, 1456, 1441, 1456],
    [293, 1457, 1440, 1457],
    [292, 1991, 1441, 1991],
    [292, 2096, 1440, 2096],
    [293, 2098, 1440, 2098],
]

list_2 = sorted(list_1, key=lambda sublist: sublist[0])

print(f"list_2 = [")
for alist in list_2:
    print(f"    {alist}")
print(f"]")
Gives:
Output:
list_2 = [ [292, 1456, 1441, 1456] [292, 1991, 1441, 1991] [292, 2096, 1440, 2096] [293, 1457, 1440, 1457] [293, 2098, 1440, 2098] [356, 944, 1447, 944] [356, 1226, 1447, 1226] [357, 1228, 1446, 1228] [499, 943, 1447, 943] ]



RE: sorting list of lists - pframe - Apr-17-2020

The result is something like this.

 # [[292, 943, 1447, 943], [292, 1226, 1447, 1226], [292, 1456, 1441, 1456], [292, 1991, 1441, 1991], [292, 2096, 1440, 2096]] 
list_1 represents a set of points [x1,y1,x2,y2] which form a line. So if you draw it out you can see what I am talking about. My solution above, basically eliminates those pseudo points/lines and returns one from each subset.

How I know it is there are 5 lines and in your solution it has more than 5 lines.


RE: sorting list of lists - Larz60+ - Apr-17-2020

There are 9 sub lists in your list_1 data.