Python 将列表合并为元组对(x,y)

Python 将列表合并为元组对(x,y),python,list,tuples,itertools,Python,List,Tuples,Itertools,我正在尝试组合通过sys.argv传入的成对数字。 例如: 我的目标是将这些转换为元组中的两个。 例如: ((-35.12323,112.76767),(-36.33345,112.76890),(-33.68689,111.8980)) 这是我到目前为止尝试过的方法,但是当我将结果传递给Shapely Point和Polygon方法时,它遇到了一个问题 from shapely.geometry import Polygon from shapely.geometry import Poin

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

我的目标是将这些转换为元组中的两个。 例如:

((-35.12323,112.76767),(-36.33345,112.76890),(-33.68689,111.8980))
这是我到目前为止尝试过的方法,但是当我将结果传递给Shapely 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中很常见,但我在该模块中似乎找不到任何可以让您成对抓取项目的东西

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


zip
可以替换为生成迭代器而不是列表的迭代器。

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

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

或者可能:

point = Point(*args_to_tuple(sys.argv[1:3])[0])
不知道shapely API,我不确定

至于将参数转换为成对的元组,您的方法做得很好。然而,如果您想要一个预打包的无障碍解决方案,我会看看pytoolz将成对分组在一起的方法。还要看看Cytolz,它努力使这些方法在性能上与C相当

编辑

我注意到你的方法中有一个错误。您没有在循环中从args\u到tuple方法递增i!以下是一个修订版,您可以在其中填充多段列表:

polylist = [(arglist[i],arglist[i+1]) for i in xrange(0,len(arglist),2)]
您可以压缩相同的迭代器对象以获得所需的对:

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
在同一迭代器对象上被调用两次,以所需的方式配对参数

对于Python3,您可以只使用映射,因为映射返回一个iterable映射对象,而不是生成器表达式

%%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
包装map返回的列表

%%python2

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

谢谢你们给我指出了正确的方向!这是我的解决方案,供将来参考。我不知道为什么我的垃圾桶方法不起作用,但这似乎是一种很简单的方法

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

这很有效,我很感激,但这不是更精确地返回了一个“元组列表”吗?TigerhawkT3的答案也是如此。@KennyPowers是的,它返回一个元组列表,但如果您需要一个包含元组的元组,则始终可以执行此操作
元组(zip(args[::2],args[1::2])
args[::2]
是一个列表切片,它构造了一个由奇数元素组成的新列表。阅读更多关于它的信息谢谢你的澄清,我忘记了列表切片的跳过部分…非常有用!最后一个问题,这里的两个答案都包含了条件。当参数被传递到python脚本中并像sys.argv[1:]那样使用时,它们是字符串列表,这意味着str.split()方法不适用于这种情况。@KennyPowers如果您有点列表而不是字符串,那么只需替换
map
调用中的最后一个参数即可。无论如何,答案中最重要的部分是关于使用
zip
和列表切片,而不是关于将数据(字符串或字符串列表)转换为floats列表。使用此答案,输入将是字符串列表,而不是由空格分隔的字符串。输入来自sys.argv[1:]。有没有一种pythonic方法可以做到这一点并输出一组元组?然后只需使用
lst
而不是
lst.split()
,并传递
sys.argv[1://code>。只有当一个参数为偶数时,如果该解决方案抛出奇数,该方法才有效exception@madjardi-问题规定它们成对出现。数字是二维坐标。关于点构造函数,这是正确的。我试着将一些需要sys args的东西混合起来,并为多边形和点构造函数准备它们,这将分别需要一个元组元组和一个元组元组。我能够通过大量错误代码获得所需的输出,但如果一个点位于多边形中,则无法从检查中获得真正的返回,即使使用shapely手动检查这些点返回True。两个构造函数中的一个不能接受我的转换。简言之,我将以python script.py x y x y的格式传递sys args,其中第一个xy对浮点是点,后面的一切都是多边形,它可能有无限多的点来定义它。此时我的直觉是回到基础,忽略reading-from-sys.argv部分。只需从包含浮点常量的元组常量创建一个点和多边形,并确保Inside和contains方法的行为符合预期。我同意,这正是我所做的,也是我如何得出这些调用应该返回真值的结论的,不仅仅是通过查看地图。我在将sys.argv转换为成对元组的原始方法中发现了一个错误,请参见我的答案中的编辑。请编辑问题(特别是标题)以反映您不希望将列表元素组合到元组的列表/元组中,但是想了解为什么
。在
中包含
返回
错误
。也许你应该问一个新的问题Lik,我知道我的元组问题的论点出了问题,但shapely库不是,它现在正在工作,因为它被传递了一个有效的元组元组。谢谢你的帮助!我真的很喜欢这个。如果需要,也可以使用
map()
,以获得相同的结果。另外,您可以省略
split()
的参数,因为默认值是空白(但是OP首先使用的是
列表
切片,所以这有点没有意义)。
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)]
%%python3

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

a = iter(map(float, args_list)
print zip(a, a)
# [(-35.12323, 112.76767), (-36.33345, 112.7689), (-33.68689, 111.898)]
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