Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
sorting list of lists
#1
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.
Reply
#2
what have you tried?
show code working or not
Reply
#3
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?
Reply
#4
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] ]
Reply
#5
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.
Reply
#6
There are 9 sub lists in your list_1 data.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Need help with sorting lists as a beginner Realist1c 1 712 Apr-25-2023, 04:32 AM
Last Post: deanhystad
  List all possibilities of a nested-list by flattened lists sparkt 1 878 Feb-23-2023, 02:21 PM
Last Post: sparkt
  user input values into list of lists tauros73 3 1,025 Dec-29-2022, 05:54 PM
Last Post: deanhystad
  returning a List of Lists nafshar 3 1,014 Oct-28-2022, 06:28 PM
Last Post: deanhystad
  Creating list of lists, with objects from lists sgrinderud 7 1,564 Oct-01-2022, 07:15 PM
Last Post: Skaperen
  List Sorting Problem ZZTurn 5 1,281 Sep-22-2022, 11:23 PM
Last Post: ZZTurn
  Sorting List finndude 9 2,393 Jan-27-2022, 09:37 PM
Last Post: Pedroski55
  How to efficiently average same entries of lists in a list xquad 5 2,070 Dec-17-2021, 04:44 PM
Last Post: xquad
  sorting a list of lists by an element leapcfm 3 1,805 Sep-10-2021, 03:33 PM
Last Post: leapcfm
  behavior list of lists roym 5 2,036 Jul-04-2021, 04:43 PM
Last Post: roym

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020