将列表组合成元组对(x,y) - Python

时间:2015-06-11 00:44:57

标签: python tuples itertools sys shapely

我正在尝试通过sys.argv组合传递的数字对。 例如:

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

我的目标是将这些变成元组中的两个。 像这样:

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

这是我到目前为止所尝试过的,但是当我将结果传递给形状相似的Point和Polygon方法时,它会出现问题。

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

似乎这在itertools中很常见,但我似乎无法在该模块中找到任何可以让你抓住一对中的项目的东西。

提前致谢!

5 个答案:

答案 0 :(得分:2)

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可以替换为生成迭代器而不是列表的itertools.izip

答案 1 :(得分:1)

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)]

答案 2 :(得分:1)

我猜Point构造函数可能需要1对,而不是包含1对的元组?为此,您需要更改:

alt+right arrow

要:

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

或者也许:

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

在不知道形状不错的API的情况下,我不确定。

至于将参数转换为对的元组,你的方法就可以了。但是,如果你想要一个预打包的无麻烦的解决方案,我会查看pytoolz的partition_all方法,将对分组在一起。还要看看cytoolz,它努力使这些方法在性能上与C相媲美。

修改

我发现你的方法存在一个错误。你没有从你的args_to_tuple方法中增加你的循环!这是一个修订版本,您可以在其中填充多列表:

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

答案 3 :(得分:1)

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

您可以压缩相同的迭代器对象以获得所需的对:

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

对于每个元组,在同一个迭代器对象上调用zip返回next两次,以所需的方式配对你的参数。

对于python 3,你可以使用map,因为map返回一个可迭代的map对象而不是一个生成器表达式。

%%python3

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

您还可以使用python 2内置的iter来包装地图返回的列表。

%%python2

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

答案 4 :(得分:0)

谢谢你们指点我正确的方向!这是我的解决方案,供将来参考。不知道为什么我的克拉皮尔方法不起作用,但这似乎是pythonic和简单的,可以使用。

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