Python 如何将文件读取为多个多边形的嵌套坐标列表?

Python 如何将文件读取为多个多边形的嵌套坐标列表?,python,regex,python-3.x,file-io,matplotlib,Python,Regex,Python 3.x,File Io,Matplotlib,我有一个包含以下许多部分的文件: [40.742742,-73.993847] [40.739389,-73.985667] [40.74715499999999,-73.97992] [40.750573,-73.988415] [40.742742,-73.993847] [40.734706,-73.991915] [40.736917,-73.990263] [40.736104,-73.98846] [40.740315,-73.985263] [40.74364800000001,

我有一个包含以下许多部分的文件:

[40.742742,-73.993847]
[40.739389,-73.985667]
[40.74715499999999,-73.97992]
[40.750573,-73.988415]
[40.742742,-73.993847]

[40.734706,-73.991915]
[40.736917,-73.990263]
[40.736104,-73.98846]
[40.740315,-73.985263]
[40.74364800000001,-73.993353]
[40.73729099999999,-73.997988]
[40.734706,-73.991915]

[40.729226,-74.003463]
[40.7214529,-74.006038]
[40.717745,-74.000389]
[40.722299,-73.996634]
[40.725291,-73.994413]
[40.729226,-74.003463]
[40.754604,-74.007836]
[40.751289,-74.000649]
[40.7547179,-73.9983309]
[40.75779,-74.0054339]
[40.754604,-74.007836]
我需要在这些部分中阅读成对坐标的列表(每个部分由一个额外的
\n
分隔)

在一个类似的文件中(除了没有额外的换行符外,其他文件相同),我从整个文件中绘制一个多边形。我可以使用以下代码读取坐标并在matplotlib中绘制它:

mVerts = []
with open('Manhattan_Coords.txt') as f:
    for line in f:
        pair = [float(s) for s in line.strip()[1:-1].split(", ")]
        mVerts.append(pair)

plt.plot(*zip(*mVerts))
plt.show()

我如何才能完成同样的任务,除了使用多个多边形,文件中的每个多边形都用一个额外的换行符分隔?

以下是我个人最喜欢的将文件“分块”为多组以空格分隔的对象的方法:

from itertools import groupby

def chunk_groups(it):
     stripped_lines = (x.strip() for x in it)
     for k, group in groupby(stripped_lines, bool):
         if k:
             yield list(group)
我建议
ast.literal\u eval
将列表的字符串表示形式转换为实际的python列表:

from ast import literal_eval

with open(filename) as f:
     result = [[literal_eval(li) for li in chunk] for chunk in chunk_groups(f)]
给出:

result
Out[66]: 
[[[40.742742, -73.993847],
  [40.739389, -73.985667],
  [40.74715499999999, -73.97992],
  [40.750573, -73.988415],
  [40.742742, -73.993847]],
 [[40.734706, -73.991915],
  [40.736917, -73.990263],
  [40.736104, -73.98846],
  [40.740315, -73.985263],
  [40.74364800000001, -73.993353],
  [40.73729099999999, -73.997988],
  [40.734706, -73.991915]],
 [[40.729226, -74.003463],
  [40.7214529, -74.006038],
  [40.717745, -74.000389],
  [40.722299, -73.996634],
  [40.725291, -73.994413],
  [40.729226, -74.003463],
  [40.754604, -74.007836],
  [40.751289, -74.000649],
  [40.7547179, -73.9983309],
  [40.75779, -74.0054339],
  [40.754604, -74.007836]]]

以下是我个人最喜欢的将文件“分块”到由空格分隔的组中的方法:

from itertools import groupby

def chunk_groups(it):
     stripped_lines = (x.strip() for x in it)
     for k, group in groupby(stripped_lines, bool):
         if k:
             yield list(group)
我建议
ast.literal\u eval
将列表的字符串表示形式转换为实际的python列表:

from ast import literal_eval

with open(filename) as f:
     result = [[literal_eval(li) for li in chunk] for chunk in chunk_groups(f)]
给出:

result
Out[66]: 
[[[40.742742, -73.993847],
  [40.739389, -73.985667],
  [40.74715499999999, -73.97992],
  [40.750573, -73.988415],
  [40.742742, -73.993847]],
 [[40.734706, -73.991915],
  [40.736917, -73.990263],
  [40.736104, -73.98846],
  [40.740315, -73.985263],
  [40.74364800000001, -73.993353],
  [40.73729099999999, -73.997988],
  [40.734706, -73.991915]],
 [[40.729226, -74.003463],
  [40.7214529, -74.006038],
  [40.717745, -74.000389],
  [40.722299, -73.996634],
  [40.725291, -73.994413],
  [40.729226, -74.003463],
  [40.754604, -74.007836],
  [40.751289, -74.000649],
  [40.7547179, -73.9983309],
  [40.75779, -74.0054339],
  [40.754604, -74.007836]]]

roippi的想法略有不同,使用了
json
而不是
ast

import json
from itertools import groupby

with open(FILE, "r") as coodinates_file:
    grouped = groupby(coodinates_file, lambda line: line.isspace())
    groups = (group for empty, group in grouped if not empty)

    polygons = [[json.loads(line) for line in group] for group in groups]

roippi的想法略有不同,使用了
json
而不是
ast

import json
from itertools import groupby

with open(FILE, "r") as coodinates_file:
    grouped = groupby(coodinates_file, lambda line: line.isspace())
    groups = (group for empty, group in grouped if not empty)

    polygons = [[json.loads(line) for line in group] for group in groups]

在已经发布的答案中有很多巧妙的方法。他们都没问题

然而,采取显而易见但可读的方法也没有什么错

另一方面,您似乎正在处理地理数据。这种格式在任何时候都会遇到,而段分隔符通常不像额外的换行符那样明显。(有很多非常糟糕的特殊“ascii导出”格式,尤其是在晦涩难懂的专有软件中。例如,一种常见格式使用段中最后一行末尾的
F
作为分隔符(即
1.0 2.0F
)。许多其他文件根本不使用分隔符,如果距离最后一个点超过“x”距离,则需要启动新的线段/多边形。)此外,这些文件通常是多GB ascii文件,因此将整个文件读入内存可能是不切实际的


我的观点是:无论你选择哪种方法,都要确保你理解它。你会再次这样做,它会变得非常不同,很难概括。您绝对应该好好学习像
itertools
这样的库,但要确保您完全理解所调用的函数


以下是“显而易见但可读”方法的一个版本。它更加冗长,但没有人会对它的作用感到困惑。(你可以用几种稍有不同的方式编写相同的逻辑。使用对你最有意义的方式。)


在已经发布的答案中,有很多巧妙的方法。他们都没问题

然而,采取显而易见但可读的方法也没有什么错

另一方面,您似乎正在处理地理数据。这种格式在任何时候都会遇到,而段分隔符通常不像额外的换行符那样明显。(有很多非常糟糕的特殊“ascii导出”格式,尤其是在晦涩难懂的专有软件中。例如,一种常见格式使用段中最后一行末尾的
F
作为分隔符(即
1.0 2.0F
)。许多其他文件根本不使用分隔符,如果距离最后一个点超过“x”距离,则需要启动新的线段/多边形。)此外,这些文件通常是多GB ascii文件,因此将整个文件读入内存可能是不切实际的


我的观点是:无论你选择哪种方法,都要确保你理解它。你会再次这样做,它会变得非常不同,很难概括。您绝对应该好好学习像
itertools
这样的库,但要确保您完全理解所调用的函数


以下是“显而易见但可读”方法的一个版本。它更加冗长,但没有人会对它的作用感到困惑。(你可以用几种稍有不同的方式编写相同的逻辑。使用对你最有意义的方式。)


为什么新线是相关的?表格是
[#,#]
。你的意思是说可能存在将这三个坐标与其他坐标分开的
[#]、[#]、[#]、[#]、[#]、#]\n
\n[#,#]\n\n是一个多边形,在该换行符之前有任意给定数量的坐标。您可以将每一行解析为字符串,然后使用正则表达式查找每一对。是你遇到麻烦的正则表达式吗,比如去掉装饰
[,]
?我可以使用正则表达式找到每一对,并将所有这些对放入一个列表中,但我需要一种用这些对创建子列表的方法,当找到额外的换行符时,每个坐标子列表都会被截断,开始下一个坐标子列表。这个输入来自哪里?它看起来非常像是有人将每个Python列表的
repr
写入一个文件,或者将其存储为JSON。如果这是真的,为什么不直接用
ast.literal\u eval
json.load
适当地解析它呢?为什么换行符是相关的?表格是
[#,#]
。你的意思是说可能存在将这三个坐标与其他坐标分开的
[#]、[#]、[#]、[#]、[#]、#]\n
\n[#,#]\n\n是一个多边形,在该换行符之前有任意给定数量的坐标。您可以将每一行解析为字符串,然后使用正则表达式查找每一对。是你遇到麻烦的正则表达式吗,比如去掉装饰
[,]
?我可以使用正则表达式找到每一对,并将所有这些对放入一个列表中,