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?
source to share
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.
source to share
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.
source to share
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!
source to share