I wrote the Python class below, which does what I want it to do, but the data structure is a mess. Was wondering if there was a better structure I could use to get the same results but with better readable code.

Idea here is we retrieve a dataset from SQL(constructor), cluster the dataset into distinct keys(constructor), iterate through the keys and isolate the matching criteria in the dataset(organizer), pass those data chunks to map_loc_to_lat_long which will find all possible combinations of rows in the chunk and find the straight line distance between all the combination Lat Longs.

class OrderProximityModel:
    def __init__(self, date):
        self.date = str(date)
        self.order_data = OrderProxDao().Load_Order_Lat_Long_Date_Zone_Data(self.date)
        self.distinct = set([str(row.Requirements) + ' ' + str(row.Route_Date) for row in self.order_data])

    def organizer(self):
        container = []
        for date_zone in self.distinct:
            latlng = list(filter(lambda x: str(x.Requirements) + ' ' + str(x.Route_Date) == date_zone, self.order_data))
            for i in self.map_loc_to_lat_long(latlng):
                container.append((i[0][0][0], i[0][0][1], i[0][0][2], i[0][0][4], i[0][0][5], i[0][0][6]))
        return True

    def map_loc_to_lat_long(self, grouped_zone):
        converted = {}
        for row in grouped_zone:
            converted[row.LocationKey] = [row.Latitude, row.Longitude, row.DA, row.Route_Date, row.Requirements, row.DA]
        grouped_combos = self.combo_creator(converted.keys())
        return map(lambda combo: ([converted[combo[0]][2:] + [combo[0]] + [combo[1]] +
                                  ), grouped_combos)

    def combo_creator(inputs):
        out = []
        for index, value in enumerate(inputs):
            for nex_value in inputs[index + 1:]:
                out.append((value, nex_value))
        return out

closed as unclear what you're asking by Toby Speight, Quill, t3chb0t, 409_Conflict, Graipher Nov 27 '18 at 12:13

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ What are OrderProxDao, InsertHelpers, StraightLineDistance? \$\endgroup\$ – Graipher Nov 24 '18 at 10:41
self.date = str(date)

This is a pet peeve of mine. Stringly-typed variables are usually a bad idea. If you receive a datetime object, you should usually keep it as datetime until you actually need it to be a string.


If at all possible, shorten this method name. Also, methods are lowercase by convention.

self.distinct = set([str(row.Requirements) + ' ' + str(row.Route_Date) for row in self.order_data])

Here you make a generator, construct a list and then convert it to a set. Skip the list - the set constructor can accept generators directly. Better yet, if you're in a sane version of Python, just use a set literal (and use a format string):

self.distinct = {'%s %s' % (row.Requirements, row.Route_Date) for row in self.order_data}

Your container = [] / container.append() loop can be replaced by proper use of a generator. Same with out.

latlng does not (and should not) be materialized to a list. It should be left as a generator, since you only iterate over it once.


container.append((i[0][0][0], i[0][0][1], i[0][0][2], i[0][0][4], i[0][0][5], i[0][0][6]))

can be:

container.append(tuple(i[0][0][j] for j in (0, 1, 2, 4, 5, 6)))

Not the answer you're looking for? Browse other questions tagged or ask your own question.