【问题标题】:How to iterate over a list of list of lists of lists of lists... of list of pair of coordinates in python?python - 如何遍历列表列表列表列表列表的列表...在python中的坐标对列表列表?
【发布时间】:2021-04-01 11:51:54
【问题描述】:

我正在尝试遍历列表列表的列表...在 python 中的一对坐标列表,我想对这些坐标对中的每一个求和一个值,但我也想保留结构。

我认为一个例子胜过千言万语:

coordinates = [[[-15.418887, 28.180395], [-15.418887, 28.180395]],
 [[-15.794088, 28.018681], [-15.794088, 28.018681]]]

这是一个非常基本的例子,但不是真实的情况。实际上,除了一对坐标之外,每个列表都有可变长度。所以在配对坐标列表之前可能有 4 个列表,也可能是 3 个,它是可变的

我想在这些坐标中的每一个上添加 3(例如),但保持原始结构(我不想扁平化列表列表的列表 ....)

也许这对尝试回答问题很有用:

  • 我有一个 geojson 文件,我想将一个要素(一个区域)移动到另一个地方。为此,我试图将一个常数值与该区域的每个坐标的纬度和经度相加
  • 我认为这可以使用递归来完成,但我不确定如何

感谢任何帮助。

【问题讨论】:

  • 是否保证一个列表中有两个嵌套列表?
  • @Harsh 不,它可以是可变的,可以是三个、四个或更多嵌套列表。它是可变的
  • 这能回答你的问题吗? Flatten an irregular list of lists
  • 您可以将列表转换为 numpy 列表,然后简单地在列表上执行您想要的操作,例如 cd = np.array(coordinates)cd = cd + 3
  • @Renat 正如我所说,我想保留原始结构我不想展平列表列表....所以它没有用,无论如何谢谢。

标签: python list recursion data-structures


【解决方案1】:

您正在使用坐标的 3D 向量(列表列表的列表)对吗?那么您的循环应该是三倍以访问该 3D 向量上的所有变量。

for x in list: #x is a list of lists
  for y in x: #y is a list
    for z in y: #z is a pair of coordinates
      #Your code here

【讨论】:

  • 正如我所说,在我的情况下,列表的长度是可变的,因此不能保证它是 3D 矢量,但是非常感谢您的回复。
  • 在这种情况下,你可以使用这个: for x in range(0, lengh(list)): list[x] 是访问你的元素的方式它仍然允许三重循环,因为如果你列表为空,它将忽略循环
【解决方案2】:
coordinates = [[[-15.418887, 28.180395], [-15.418887, 28.180395]],
               [[-15.794088, 28.018681], [-15.794088, 28.018681]]]

def recursively_add3(l):
    if isinstance(l, float):
        return l
    
    for index, inner_list in enumerate(l):
        inner_result = recursively_add3(inner_list)
        if inner_result is not None:
            l[index] = inner_result + 3
    
    return None

recursively_add3(coordinates)

给出结果

[[[-12.418887, 31.180395], [-12.418887, 31.180395]]
, [[-12.794088, 31.018681], [-12.794088, 31.018681]]]

【讨论】:

    【解决方案3】:

    您可以使用递归函数来处理一般情况。只需检查是否有列表并递归,否则返回加法的结果:

    def add_to_list(l, n):
        if not isinstance(l, list):
            return l + n
        return [add_to_list(sub, n) for sub in l]
       
    coordinates = [[[-15.418887, 28.180395], [-15.418887, 28.180395]],[[-15.794088, 28.018681], [-15.794088, 28.018681]]]
    
    add_to_list(coordinates, 3)    
    #[[[-12.418887, 31.180395], [-12.418887, 31.180395]], [[-12.794088, 31.018681], [[-12.794088, 31.018681]]]]
    
    # A more general case:
    add_to_list([1, [2, [5, [6]]], 3], 2)
    # [3, [4, [7, [8]]], 5]
    
    # Degenerate cases
    add_to_list([], 2)
    # []
    add_to_list(5, 2) 
    # 7
    

    这假定您的嵌套数据将是数字或列表。

    【讨论】:

      【解决方案4】:

      一般map 方法仅将函数应用于随机深度嵌套列表的最内层元素:

      def map_nested(fnc, lst):
          if not isinstance(lst, list):
              return fnc(lst)
          return [map_nested(fnc, x) for x in lst]
          # or for in-place mutation:
          # lst[:] = (map_nested(fnc, x) for x in lst)
          # return lst
      
      add3 = lambda x: x+3
      
      map_nested(add3, coordinates)
      # [[[-12.418887, 31.180395], [-12.418887, 31.180395]], 
      #  [[-12.794088, 31.018681], [-12.794088, 31.018681]]]
      

      【讨论】:

      • 这是否比@SiArce 或@Mark Meyer 实现的递归方法更有效?
      • 效率是一样的。它更具可重用性,因为它提供了一种在任意嵌套级别应用任何函数(不仅仅是添加 3 或 n 的函数)的方法。我也发现它更具可读性,因为 map_nested 只专注于它的遍历任务。
      • @Ángel,另外一个区别是我的结果已经到位,另外2个返回一个新列表
      • MarkMeyer 和我的,创建并返回一个新的列表对象,而 SiAce 改变现有的。
      • @SiAce 是的,只是指出了这一点,并为我的方法添加了一个就地替代方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-27
      • 2011-09-14
      • 2022-11-22
      • 2016-07-16
      • 1970-01-01
      相关资源
      最近更新 更多