Converting a string to a list of 2 tuples

I have lines of this form:

d="M 997.14282,452.3622 877.54125,539.83678 757.38907,453.12006 802.7325,312.0516 950.90847,311.58322 Z"

      

which are the (x, y)

coordinates of the pentagon (the first and last letters are metadata and are ignored). What I want is a list of 2 tuples that will represent the coordinates in floating points without any steepness:

d = [(997.14282, 452.3622), (877.54125, 539.83678), (757.38907, 453.12006), (802.7325,312.0516), (950.90847, 311.58322)]

      

Trimming the line was simple:

>>> d.split()[1:-2]
['997.14282,452.3622', '877.54125,539.83678', '757.38907,453.12006', '802.7325,312.0516']

      

but now I want to create tuples succinctly. This clearly didn't work:

>>> tuple('997.14282,452.3622')
('9', '9', '7', '.', '1', '4', '2', '8', '2', ',', '4', '5', '2', '.', '3', '6', '2', '2')

      

Taking the original line, I could write something like this:

def coordinates(d):
    list_of_coordinates = []
    d = d.split()[1:-2]
    for elem in d:
        l = elem.split(',')
        list_of_coordinates.append((float(l[0]), float(l[1])))
    return list_of_coordinates

      

which works great:

>>> coordinates("M 997.14282,452.3622 877.54125,539.83678 757.38907,453.12006 802.7325,312.0516 950.90847,311.58322 Z")
[(997.14282, 452.3622), (877.54125, 539.83678), (757.38907, 453.12006), (802.7325, 312.0516)]

      

However, this processing is a small and trivial part of a larger program, and I would prefer it as short and concise as possible. Can anyone show me a less surefire way to convert a string to a 2-tuple list?

+3


source to share


3 answers


Note, not sure if this is necessary - when you do d.split()[1:-2]

, you lose the last coordinate. Assuming this is not intentional, one liner for this would be -

def coordinates1(d):
    return [tuple(map(float,coords.split(','))) for coords in d.split()[1:-1]]

      



If the loss of the last coordinate is intentional, use [1:-2]

in the above code.

+2


source


You can do this in one line using a list comprehension.

x = [tuple(float(j) for j in i.split(",")) for i in d.split()[1:-2]]

      



This goes through d.split()[1:-2]]

, each pair that needs to be grouped together, separate them with a comma, convert each element to this to a float, and group them into a tuple.

Also, you can use d.split()[1:-1]

because using -2

cuts out the last pair of coordinates.

+2


source


So far so fine, this can be condensed using a list comprehension or some functional element (I mean "map"):

    def coordinates(d):
        d = d[2:-2].split() # yeah, split here into pairs
        d = map(str.split, d, ","*len(d)) # another split, into tokens
        # here we'd multiplied string to get right size iterable
        return list(map(tuple, d)) # and last map with creating list
        # from "map object"

      

In Couse, it can be reduced to a single line with a list, but the read accuracy will also be reduced (while the code is being hard-read right now). And while Guido hates functional programming, I find it more logical ... After some practice. Good luck!

0


source







All Articles