Transforming a list of two-dimensional coordinates into a flat list of relative changes I have a little function that parse a nested list of coordinates into a flat list of compressed coordinates. By compressed coordinates, I mean that only the delta (distance) between each coordinates are stored in the list and the float coordinates are transformed in integer.

input = [[-8081441,5685214], [-8081446,5685216], [-8081442,5685219], [-8081440,5685211], [-8081441,5685214]]
output = [-8081441, 5685214, 5, -2, -4, -3, -2, 8, 1, -3]

def parseCoords(coords):
    #keep the first x,y coordinates
    parsed = [int(coords[0][0]), int(coords[0][1])]
    for i in xrange(1, len(coords)):
        parsed.extend([int(coords[i-1][0]) - int(coords[i][0]), int(coords[i-1][1]) - int(coords[i][1])])
    return parsed

parsedCoords = parseCoords(input)


As the input list is really big, is there a way to improve the function, maybe by using generators or list comprehension?
for i in xrange(1, len(coords)) is a red flag, since it is preferred in python to iterate directly over the elements rather than the indices. If you trully need the indices, you can still use enumerate.

Here it would look like

for i, coord in enumerate(coords[1:]):
    previous = coords[i]
    parsed.extend([int(previous[0] - coord[0]), int(previous[1] - coord[1])])


which seems worse as it


creates a copy of coords when slicing it;
still uses an index to retrieve the previous element.


Instead, it seems better to convert the list into an iterator an manually handle the current/previous coordinates. Something like:

def parse_coordinates(coords):
    iterator = iter(coords)
    previous_x, previous_y = iterator.next()
    parsed = [int(previous_x), int(previous_y)]
    for current_x, current_y in iterator:
        parsed.append(int(previous_x - current_x))
        parsed.append(int(previous_y - current_y))
        previous_x, previous_y = current_x, current_y
    return parsed


You can note the use of append instead of extend that will avoid building a temporary list. append try to be smart when resizing the underlying array so that two consecutive appends should not have more performance hit than extend.

But all in all, using append or extend in a for loop is often better written using a list-comprehension or a generator. You can easily turn this function into a generator by turning these append into yields:

def parse_coordinates(coords):
    iterator = iter(coords)
    previous_x, previous_y = iterator.next()
    yield int(previous_x)
    yield int(previous_y)
    for current_x, current_y in iterator:
        yield int(previous_x - current_x)
        yield int(previous_y - current_y)
        previous_x, previous_y = current_x, current_y


There is an other advantage to this approach: if the coords parameter is empty, your approach using coords[0] and the first one building a list using iterator.next() will crash raising either an IndexError or a StopIteration.

This generator can easily be fed to the list constructor or a for loop and won't crash; producing either an empty list or not entering the loop.



Lastly, you could drop manually managing the previous/current thing by using itertools.tee which is the key feature of the pairwise recipe:

from itertools import tee, izip


def parse_coordinates(coords):
    prev, cur = tee(coords)
    x, y = cur.next()
    yield int(x)
    yield int(y)
    for (previous_x, previous_y), (current_x, current_y) in izip(prev, cur):
        yield int(previous_x - current_x)
        yield int(previous_y - current_y)