How to sort and put together several lines into a longer line?

Viewed 48

I am looking for a way to sort and combine objects / segments into one connected segment. I have a list of objects and I have to arrange them so that the end of one matches the beginning of the other (some of them can be reversed), is there some way to do it, thank you in advance.

class Line:
def __init__(self, name, start, end):
    self.name = name
    self.startPoint = start
    self.endPoint = end 

def __repr__(self):
    return f"<{self.name}{self.startPoint}-{self.endPoint}>"

a = Line("d", (4, 4), (3, 3))
b = Line("b", (2, 2), (3, 3)) 
c = Line("c", (1, 1), (2, 2)) 
d = Line("a", (0, 0), (1, 1)) 
l = [a, b, c, d]

#result
# a.reverse
sorted_l = [d, c, b, a]
2 Answers

A simple solution is to use the list.sort() function to sort a collection of objects (using some attribute) in Python.

In your case you can use a lambda function to handle the sorting:

list_objects = [a, b, c, d]

use lambda in sort() method, I have specified class variable name (x.startPoint) for sorting you can use others if you want.

list_objects.sort(key=lambda x: x.startPoint)

result will be as below:

[<a (0, 0)-(1, 1)>, <c (1, 1)-(2, 2)>, <b (2, 2)-(3, 3)>, <d (4, 4)-(3, 3)>]

My solution, arranges and creates sorted arrays of segments:

class Section:
def __init__(self, name, start, end, kml:list):
    sel.kml = kml # list with tuples
    self.name = name
    self.startPoint = start
    self.endPoint = end 

def rev_kml(self):
    self.kml.reverse()
    self.startPoint = self.kml[0]
    self.endPoint = self.kml[-1]    

def __repr__(self):
    return f"<{self.name}{self.startPoint}-{self.endPoint}>"


class RoutingSections:

def __init__(self, obj_lst):
    self.lst = obj_lst.copy()
    self.result = []
    self.first_obj = obj_lst[0]   
    
@staticmethod
def proceed_forward(obj, lista):
    for i in lista:
        if obj.endPoint == i.startPoint:
            lista.remove(i)
            return i

        elif obj.endPoint == i.endPoint:
            lista.remove(i)
            i.rev_kml()
            return i
        
@staticmethod
def proceed_back(obj, lista):
    for i in lista:
        if obj.startPoint == i.endPoint:
            lista.remove(i)
            return i

        elif obj.startPoint == i.startPoint:
            lista.remove(i)
            i.rev_kml()
            return i

def sort(self):
    end_list = False
    obj = self.first_obj
  
    while not end_list:
        x = RoutingSections.proceed_forward(obj, self.lst)
        if not x:
            end_list = True   
        if x:
            obj = x
            self.result.append(x)

    end_list = False
    obj =  self.first_obj
    
    while not end_list:
        x = RoutingSections.proceed_back(obj, self.lst)
        if not x:
            end_list = True
        if x:
            obj = x
            self.result.insert(0, x)
    return self.result
Related