【问题标题】:Is there a way of splitting a list of coordinates into separate parts, based on repeating values?有没有办法根据重复值将坐标列表拆分为单独的部分?
【发布时间】:2019-09-02 04:36:26
【问题描述】:

我正在尝试使用 matplotlib.pyplot 根据一系列坐标绘制多个单独的几何图形。我当前的坐标列表,包含两个几何图形如下所示:

coords = [(0.0, -0.31), (2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]    

我想根据重复值将此列表拆分为单独的列表,以创建和绘制闭合几何图形。目前,这组坐标正确地绘制了两个形状,但它们通过一条线连接在一起。我希望这些是分开的,所以连接它们的线不会绘制。

是否可以拆分此列表,以便在再次达到第一个值 (0, -0.31) 时(即关闭几何图形)创建一个新列表,其中包含该点的坐标?这将分离出与闭合形状相关的所有坐标,让我可以绘制它。

原始坐标列表中可能包含 n 个几何图形,因此理想情况下,解决方案会将所有这些拆分为单独的坐标对列表,其中第一个和最后一个坐标对相同。

【问题讨论】:

    标签: python list split coordinates


    【解决方案1】:

    你可以使用itertools.groupby:

    import itertools
    coords = [(0.0, -0.31), (2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)] 
    c = [[a, list(b)] for a, b in itertools.groupby(coords, key=lambda x:x == coords[0])]
    new_result = [c[i][-1]+c[i+1][-1] for i in range(0, len(c), 2)]
    

    输出:

    [[(0.0, -0.31), (2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33)], [(0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]]
    

    编辑:要查找所有组,您可以使用生成器:

    def groups(data):
      for i, a in enumerate(data):
         c = [[a, list(b)] for a, b in itertools.groupby(data[i:], key=lambda x:x == a)]
         yield [c[i][-1]+c[i+1][-1] for i in range(0, len(c)-1, 2)]
    
    print(list(groups(coords)))
    

    输出:

    [[[(0.0, -0.31), (2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33)], [(0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43)]], [[(2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(6.73, -0.43), (2.73, -0.43)]], []]
    

    【讨论】:

    • 这很棒。我看到您已拆分列表,因此 (0.0, -0.31) 是 new_result 中第二个列表的第一对。我不熟悉itertools;有没有办法让 new_result 中的每个列表都具有相同的开始和结束坐标对?这样 new_result 看起来像 [[(0.0,-0.31),...(0.0, -0.31)], [(2.73, -0.43),...(2.73, -0.43)]]?谢谢!
    【解决方案2】:

    我会使用自定义生成器:

    from itertools import takewhile
    
    coords = [(0.0, -0.31), (2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]
    
    def coord_list(coords):
        coord_iter = iter(coords)
        while True:
            start = next(coord_iter)
            yield [start, *takewhile(lambda x: x != start, coord_iter), start]
    
    list(coord_list(coords))
    

    输出:

    [[(0.0, -0.31),
      (2.73, -0.31),
      (2.73, 0.33),
      (2.02, 0.95),
      (1.77, 2.44),
      (1.39, 4.76),
      (0.64, 4.76),
      (0.0, 3.46),
      (0.0, 0.33),
      (0.0, -0.31)],
     [(2.73, -0.43),
      (2.73, -3.5),
      (6.73, -3.5),
      (6.73, -3.0),
      (6.73, -2.0),
      (6.73, -0.43),
      (2.73, -0.43)]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-15
      • 2022-06-11
      • 2021-08-13
      • 2022-01-19
      • 2023-02-04
      • 2016-05-02
      • 2020-05-08
      • 1970-01-01
      相关资源
      最近更新 更多