我有一个字符串,其中包含代表多边形的坐标列表。在该列表中,每个多边形具有相同的起始和结束坐标。我需要将每个多边形放在单独的字符串(或列表)中。
'17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875, 28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.706947326660156, 28.865726470947266 -28.761619567871094'
所以从这个简单的例子中我需要有两个元素:
One = '17 .17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875'
两个= '28 .865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.706947326660156,28.865726470947266 -28.761619567871094'*
字符串中可能有更多的多边形需要分开。我只能使用标准的python库
s='17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875, 28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.706947326660156, 28.865726470947266 -28.761619567871094'
#convert the input in a list of points
coordinates = [tuple(map(float,el.split())) for el in s.split(",")]
polygons = []
#find the polygons
while coordinates:
ind = coordinates[1:].index(coordinates[0])
polygons.append(coordinates[0:ind+2])
coordinates = coordinates[ind+2:]
#output
[(17.17165756225586, -28.102264404296875), (17.184370040893555, -28.200496673583984), (17.1986083984375, -28.223613739013672), (17.17165756225586, -28.102264404296875)]
[(28.865726470947266, -28.761619567871094), (28.80694007873535, -28.75750160217285), (28.792499542236328, -28.706947326660156), (28.865726470947266, -28.761619567871094)]
这是另一种方法,这种方法适用于任何字符串长度,只要它基于您提供的输入格式。
strng = "17.17165756225586,-28.102264404296875,17.184370040893555,-28.200496673583984,17.1986083984375,-28.223613739013672,17.17165756225586,-28.102264404296875,28.865726470947266,-28.761619567871094,28.80694007873535,-28.75750160217285,28.792499542236328,-28.706947326660156,28.865726470947266,-28.761619567871094"
#convert to list of tuples
l_tuple = zip(*[iter(strng.split(','))]*2)
#get list of duplicate indexes
l_index=[]
for Tuple in l_tuple:
x = [i for i,x in enumerate(l_tuple) if x == Tuple]
if len(x)>1:
l_index.append(x)
#get separate lists
New_list = []
for IND in list(set(map(tuple,l_index))):
print(l_tuple[IND[0]:IND[1]+1])
New_list.append(l_tuple[IND[0]:IND[1]+1])
>>> lst = ['17.17165756225586 -28.102264404296875','17.184370040893555 -28.200496673583984',\
... '17.1986083984375 -28.223613739013672','17.17165756225586 -28.102264404296875',' 28.865726470947266 -28.761619567871094',\
... '28.80694007873535 -28.75750160217285','28.792499542236328 -28.706947326660156', '28.865726470947266 -28.761619567871094']
>>> lst1 =[]
>>> for cord in lst:
... if cord not in lst1:
... lst1.append(cord)
...
>>> print(lst1)
['17.17165756225586 -28.102264404296875', '17.184370040893555 -28.200496673583984', '17.1986083984375 -28.223613739013672', ' 28.865726470947266 -28.761619567871094', '28.80694007873535 -28.75750160217285', '28.792499542236328 -28.706947326660156', '28.865726470947266 -28.761619567871094']
这是一个相当丑陋但工作正常的解决方案,只是将明显的方法放入代码中。
# Note that your string has inconsistent separators -- sometimes ',', sometimes ', '.
# I'm going to separate on `,` and not worry about it -- you need to work out
# what the correct separator is.
s = '17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875, 28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.706947326660156, 28.865726470947266 -28.761619567871094'
coordinates = s.split(',')
polygon = []
polygons = []
new = True
for coordinate in coordinates:
polygon.append(coordinate)
if new:
start = coordinate
new = False
elif coordinate == start:
polygons.append(polygon)
polygon = []
new = True
result = [",".join(polygon) for polygon in polygons]
print(result)
Out:
['17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875', ' 28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.706947326660156, 28.865726470947266 -28.761619567871094']
既然您的输入已经是一个字符串(并且您的预期结果也是?),您可以使用带有反向引用的regular expression (([^,]+).*\2)
来尝试这种超级懒惰的解决方案。在这里,[^,]+
是第一个坐标对,.*
是另一对,而\2
是第一对。
>>> s = '17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875, 28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.706947326660156, 28.865726470947266 -28.761619567871094'
>>> re.findall(r"(([^,]+).*\2)", s)
[('17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875',
'17.17165756225586 -28.102264404296875'),
(' 28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.706947326660156, 28.865726470947266 -28.761619567871094',
' 28.865726470947266 -28.761619567871094')]
或者使用finditer
并获取group
直接获取字符串列表:
>>> [m.group() for m in re.finditer(r"(([^,]+).*\2)", s)]
['17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875',
' 28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.706947326660156, 28.865726470947266 -28.761619567871094']
经过一些后期处理,得到实际的数字对列表(_
是findall
的结果; finditer
丢弃了[0]
):
>>> [[tuple(map(float, y.split())) for y in x[0].split(",")] for x in _]
[[(17.17165756225586, -28.102264404296875),
(17.184370040893555, -28.200496673583984),
(17.1986083984375, -28.223613739013672),
(17.17165756225586, -28.102264404296875)],
[(28.865726470947266, -28.761619567871094),
(28.80694007873535, -28.75750160217285),
(28.792499542236328, -28.706947326660156),
(28.865726470947266, -28.761619567871094)]]
对于更长的字符串,这可能不是最快的解决方案,但我没有时间。
如何将长字符串与每个“,”分开并将其放入数组中。然后创建一个for循环并执行:
intStart = 0;
if (array[intStart] == array[i]){
for(j=0; j<i; j++){
string += array[j];
}
arrPolygons.push(string);
intStart = i+1;
}
因此,当起始坐标与值匹配时,将这些值之间的所有变量添加到字符串中。然后将字符串推送到另一个数组然后开始将下一个值与之后的数据进行比较。
顺便说一下,这只是一个伪代码示例。
希望这可以帮助
s = '17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875, 28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.706947326660156, 28.865726470947266 -28.761619567871094'
coord = s.split(',')
inpoly = False
poly = [[]]
start = None
for i in coord:
poly[-1].append(i)
if i == start:
poly.append([])
inpoly = False
if not inpoly:
start = i
inpoly = True
print(poly)
输出:
[['17.17165756225586 -28.102264404296875', '17.184370040893555 -28.200496673583984', '17.1986083984375 -28.223613739013672', '17.17165756225586 -28.102264404296875'], [' 28.865726470947266 -28.761619567871094', '28.80694007873535 -28.75750160217285', '28.792499542236328 -28.706947326660156', ' 28.865726470947266 -28.761619567871094']]
我非常喜欢@newbie的简洁解决方案。这是一个稍微冗长/可读的:
s = '17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875, 28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.706947326660156, 28.865726470947266 -28.761619567871094'
vertices = [c.strip() for c in s.split(",")] # split and clean vertex data
polygons = []
current_polygon = None
for vertex in vertices:
if current_polygon is None: # start a new polygon
current_polygon = [vertex]
elif current_polygon[0] == vertex: # conclude the current polygon
current_polygon.append(vertex)
polygons.append(current_polygon)
current_polygon = None
else: # continue the current polygon
current_polygon.append(vertex)
for polygon in polygons: # print polygons
print(",".join(polygon))
输入数据...
lst = [
'17.17165756225586 -28.102264404296875',
'17.184370040893555 -28.200496673583984',
...
'17.1986083984375 -28.223613739013672',
'17.17165756225586 -28.102264404296875',
'28.865726470947266 -28.761619567871094',
...
'28.80694007873535 -28.75750160217285',
'28.792499542236328 -28.706947326660156',
'28.865726470947266 -28.761619567871094',
]
lst1 = []
for cord in lst:
if cord not in lst1:
lst1.append(cord)
print(lst1)
输出:
[
'17.17165756225586 -28.102264404296875',
'17.184370040893555 -28.200496673583984',
'17.1986083984375 -28.223613739013672',
'28.865726470947266 -28.761619567871094',
'28.80694007873535 -28.75750160217285',
'28.792499542236328 -28.706947326660156',
'28.865726470947266 -28.761619567871094',
]
递归方法:
def split_polygons(s):
if s == '': # base case
return []
start, rest = s.split(',', 1)
head, tail = map(lambda x: x.strip(', '), rest.split(start, 1))
poly = start + ',' + head + start # reconstruct the first polygon
return [poly] + split_polygons(tail)
>>> p = '17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875, 28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.706947326660156, 28.865726470947266 -28.761619567871094'
>>> split_polygons(p)
['17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,17.1986083984375 -28.22361373901367217.17165756225586 -28.102264404296875', '28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,28.792499542236328 -28.70694732666015628.865726470947266 -28.761619567871094']
c = '17.17165756225586 -28.102264404296875,17.184370040893555 -28.200496673583984,\
17.1986083984375 -28.223613739013672,17.17165756225586 -28.102264404296875,\
28.865726470947266 -28.761619567871094,28.80694007873535 -28.75750160217285,\
28.792499542236328 -28.706947326660156, 28.865726470947266 -28.761619567871094'
c = [i.strip(' ') for i in c.split(',')]
i = 0
lst = []
while i!=len(c):
out = c[i]
j = i+1
while c[i]!=c[j]:
out = out+','+c[j]
j = j+1
out = out+','+c[j]
lst.append(out)
out=''
i = j+1