Concatenate a list into pairs of tuples (x, y)

I am trying to combine pairs of numbers passed through sys.argv

. Example:

python myscript.py -35.12323 112.76767 -36.33345 112.76890 -33.68689 111.8980

      

My goal would be to turn them into sets of two in tuples. It seems like this:

((-35.12323,112.76767),(-36.33345,112.76890),(-33.68689,111.8980))

      

This is what I have tried so far, but a problem arises when I pass the results to the Shapely Point and Polygon methods.

from shapely.geometry import Polygon
from shapely.geometry import Point
import sys

def args_to_tuple(list):
    arglist = []

    for coord in list:
        arglist.append(float(coord))

    i = 0
    polylist = []

    for xory in arglist:
        tmp = (arglist[i],arglist[i+1])
        polylist.append(tmp)

    return tuple(polylist)


poly = Polygon(args_to_tuple(sys.argv[3:]))

# xy pair for point is first two sys args
point = Point(args_to_tuple(sys.argv[1:3]))

print point.within(poly) # should result in true, but doesn't
print poly.contains(point) # should result in true, but doesn't

      

It seems like it would be something common in itertools, but I can't find anything in this module that allows you to take items in pairs.

+3


source to share


5 answers


In [10]: args_str = '-35.12323 112.76767 -36.33345 112.76890 -33.68689 111.8980'

In [11]: args = map(float, args_str.split())

In [12]: args
Out[12]: [-35.12323, 112.76767, -36.33345, 112.7689, -33.68689, 111.898]

In [13]: zip(args[::2], args[1::2])
Out[13]: [(-35.12323, 112.76767), (-36.33345, 112.7689), (-33.68689, 111.898)]

      



zip

can be replaced with itertools.izip

which produces an iterator instead of a list.

+2


source


def args_to_tuple(lst):
    it = iter(map(float, lst.split()))
    return [(item, next(it)) for item in it]

      




>>> a = '-35.12323 112.76767 -36.33345 112.76890 -33.68689 111.8980'
>>> args_to_tuple(a)
[(-35.12323, 112.76767), (-36.33345, 112.7689), (-33.68689, 111.898)]

      

+1


source


I would guess that the Point constructor will probably take 1 pair, rather than a tuple containing 1 pair? To do this, you will need to change:

point = Point(args_to_tuple(sys.argv[1:3]))

      

To:

point = Point(args_to_tuple(sys.argv[1:3])[0])

      

Or maybe:

point = Point(*args_to_tuple(sys.argv[1:3])[0])

      

Not knowing the slender API, I'm not sure.

As far as converting the arguments to a tuple of pairs, your method works fine. However, if you want a hassle-free prepackaged solution, I would look at the pytoolz partition_all method for grouping pairs together. Also have a look at cytoolz, which aims to make these methods comparable to C in performance.

EDIT

I noticed an error in your method. You don't increment me in your loop from the args_to_tuple method! Here's a revised version where you populate the polylist:

polylist = [(arglist[i],arglist[i+1]) for i in xrange(0,len(arglist),2)]

      

+1


source


args_list = "-35.12323 112.76767 -36.33345 112.76890 -33.68689 111.8980".split()

      

You can anchor the same iterator object to get the pairs you want:

a = (float(x) for x in args_list)
zip(a, a)
# [(-35.12323, 112.76767), (-36.33345, 112.7689), (-33.68689, 111.898)]

      

For each tuple that zip returns next

, it is called twice on the same iteration object, concatenating your arguments as desired.

For python 3 you can just use a map since map returns an iterable map object instead of a generator expression.

%%python3

a = map(float, args_list)
print(tuple(zip(a, a)))
# ((-35.12323, 112.76767), (-36.33345, 112.7689), (-33.68689, 111.898))

      

You can also wrap the list returned by the map using the built in iter

for python 2.

%%python2

a = iter(map(float, args_list)
print zip(a, a)
# [(-35.12323, 112.76767), (-36.33345, 112.7689), (-33.68689, 111.898)]

      

+1


source


Thanks guys for pointing me in the right direction! Here's my solution for future reference. Not sure why my crappier method didn't work, but it seems goofy and simple enough to go.

from shapely.geometry import Polygon
from shapely.geometry import Point
import sys

#point = Point(38.27269, -120.98145)

# Point
l = map(float, sys.argv[1:3])
point = Point(tuple((l[0],l[1])))


# Polygon
l = map(float, sys.argv[3:])
poly = Polygon(tuple(zip(l[::2], l[1::2])))

# Test
print point.within(poly) # should result in true
print poly.contains(point) # should result in true

      

0


source







All Articles