4
\$\begingroup\$

It's a function to split the coordinates to some small blocks. For example, some country has a coordinates of north-east and south-west, two diagonals.

If I set the interval to 0.05, it will returns all the coordinates with an interval of 0.05 (or some very close value).

Note: you could regard the blocks as square, and the length of it's edge is 'interval'

For these function, how can simplify it and make it more readable?

Sample results:

[{'ne_lng': -53.0, 'sw_lat': 71.97411764705882, 'interval': 0.05, 'sw_lng': -53.04941176470588, 'ne_lat': 72.0}, {'ne_lng': -53.0, 'sw_lat': 71.94823529411764, 'interval': 0.05, 'sw_lng': -53.04941176470588, 'ne_lat': 71.97411764705882}]





Country = {
    'ne_lat' : 89.000000,
    'ne_lng' : 179.000000,
    'sw_lat' : -89.000000,
    'sw_lng' : -179.000000
}

def getCoordinate(Country, interval):
    ne_lng = Country['ne_lng']
    ne_lat = Country['ne_lat']
    sw_lng = Country['sw_lng']
    sw_lat = Country['sw_lat']
    interval = float(interval)
    i = 0
    temp = ne_lng
    lngList = []
    n = int((ne_lng - sw_lng)/interval)+1
    for _ in range(n):
        i += 1
        lngList.append(temp)
        temp -= (ne_lng - sw_lng) / n
    i = 0
    temp = ne_lat
    latList = []
    n = int((ne_lng - sw_lng)/interval)+1
    for _ in range(n):
        i += 1
        latList.append(temp)
        temp -= (ne_lat - sw_lat) / n
    coordinate = []
    for ki, vi in enumerate(lngList):
        for kj, vj in enumerate(latList):
            if ki == n-1 or kj == n-1:
                pass
            else:
                coordinate.append([vi, vj, lngList[ki+1], latList[kj+1]])
    newList = []
    for host in coordinate:
        newDict = {
            'ne_lng': host[0],
            'ne_lat': host[1],
            'sw_lng': host[2],
            'sw_lat': host[3],
            "interval": interval
        }
        # print posts.insert(newDict)
        newList.append(newDict)
    return newList
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

Here are three ways your code could be made more pythonic (which I consider to be more readable):

Use python keyword expansion:

Python allows the expansion of a dict object when calling a function. This means we can change:

def getCoordinate(Country, interval):
    ne_lng = Country['ne_lng']
    ne_lat = Country['ne_lat']
    sw_lng = Country['sw_lng']
    sw_lat = Country['sw_lat']

To this:

def get_coordinate(ne_lng, ne_lat, sw_lng, sw_lat, interval):

if we call it like:

get_coordinate(interval=100, **Country)

Use list comprehension to remove loop boilerplate:

This:

i = 0
temp = ne_lng
lngList = []
n = int((ne_lng - sw_lng)/interval)+1
for _ in range(n):
    i += 1
    lngList.append(temp)
    temp -= (ne_lng - sw_lng) / n
i = 0
temp = ne_lat
latList = []
n = int((ne_lng - sw_lng)/interval)+1
for _ in range(n):
    i += 1
    latList.append(temp)
    temp -= (ne_lat - sw_lat) / n

becomes:

n = 1 + int((ne_lng - sw_lng) / interval)
lng_list = [
    ne_lng - (ne_lng - sw_lng) * i / n for i in range(n)]

n = 1 + int((ne_lng - sw_lng) / interval)
lat_list = [
    ne_lat - (ne_lat - sw_lat) * i / n for i in range(n)]

Build the output format while iterating:

This code takes the product of two lists and builds a list of lists of the results. It then iterates through that list to generate a list of dicts.

for ki, vi in enumerate(lngList):
    for kj, vj in enumerate(latList):
        if ki == n-1 or kj == n-1:
            pass
        else:
            coordinate.append([vi, vj, lngList[ki+1], latList[kj+1]])
newList = []
for host in coordinate:
    newDict = {
        'ne_lng': host[0],
        'ne_lat': host[1],
        'sw_lng': host[2],
        'sw_lat': host[3],
        "interval": interval
    }
    # print posts.insert(newDict)
    newList.append(newDict)
return newList

But it is easy to build the dict during the first loop, which will elimnate one entire loop. In addition, the result list can be produced with a list comprehension, which gives:

return [
    {
        'ne_lng': vi,
        'ne_lat': vj,
        'sw_lng': lng_list[ki + 1],
        'sw_lat': lat_list[kj + 1],
        "interval": interval,
    }
    for ki, vi in enumerate(lng_list[:-1])
    for kj, vj in enumerate(lat_list[:-1])
]

Note:

I imagine the second line of:

n = 1 + int((ne_lng - sw_lng) / interval)

is a bug since at that point a lat is going to be calculated.

Code:

For completeness here is the entire code I ended up with:

def get_coordinate(ne_lng, ne_lat, sw_lng, sw_lat, interval):
    interval = float(interval)

    n = 1 + int((ne_lng - sw_lng) / interval)
    lng_list = [
        ne_lng - (ne_lng - sw_lng) * i / n for i in range(n)]

    n = 1 + int((ne_lng - sw_lng) / interval)
    lat_list = [
        ne_lat - (ne_lat - sw_lat) * i / n for i in range(n)]

    return [
        {
            'ne_lng': vi,
            'ne_lat': vj,
            'sw_lng': lng_list[ki + 1],
            'sw_lat': lat_list[kj + 1],
            "interval": interval,
        }
        for ki, vi in enumerate(lng_list[:-1])
        for kj, vj in enumerate(lat_list[:-1])
    ]


Country = {
    'ne_lat': 89.000000,
    'ne_lng': 179.000000,
    'sw_lat': -89.000000,
    'sw_lng': -179.000000
}

new_data = get_coordinate(interval=100, **Country)
old_data = getCoordinateOrig(Country, 100)
assert new_data == old_data
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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