【问题标题】:How can I have two for loops in the same list but the second one to start from the next value of the first loop?如何在同一个列表中有两个 for 循环,但第二个从第一个循环的下一个值开始?
【发布时间】:2021-05-02 15:46:11
【问题描述】:

我正在尝试编写一个代码,其中我有一个向量列表,我必须找到每个向量与其余向量之间的角度。(我正在研究 mediapipe 的手部地标)。 到目前为止,我的代码是这样的:

vectors = [thumb_cmc_vec, thumb_mcp_vec, thumb_ip_vec, thumb_tip_vec, index_mcp_vec, index_pip_vec,
                           index_dip_vec, index_tip_vec, middle_mcp_vec, middle_pip_vec, middle_dip_vec, middle_tip_vec,
                           ring_mcp_vec, ring_pip_vec, ring_dip_vec, ring_tip_vec, pinky_mcp_vec, pinky_pip_vec,
                           pinky_dip_vec, pinky_tip_vec]

                for vector in vectors:
                    next_vector = vector + 1
                    print(vector)
                    for next_vector in vectors:
                        print(next_vector)
                        M = (np.linalg.norm(vector) * np.linalg.norm(next_vector))
                        ES = np.dot(vector, next_vector)
                        th = math.acos(ES / M)
                        list.append(th)
                        print(list)

其中 M = 当前向量集范数的乘积,ES = 向量的标量积和 th = 向量的角度。 我的问题是变量next_vector 总是从列表的第一个向量开始 for 循环,即使我希望它从前一个循环的下一个向量开始,以免产生重复的结果。此外,当两个循环都在第三个向量(thumb_ip_vec)上时,我收到此错误 th = math.acos(ES / M) ValueError:数学域错误。有没有办法解决这个问题?谢谢!

【问题讨论】:

    标签: python list nested-for-loop


    【解决方案1】:

    我认为您可以遍历列表索引(使用range(len(vectors) - 1))并通过索引访问元素,而不是遍历每个元素

    for i in range(len(vectors) - 1):
        # Iterate from 0 to len(vectors) -1
        vector = vectors[i]
        for j in range(i + 1, len(vectors)):
            # Iterate from index i + 1 to len(vectors)
            next_vector = vectors[j]
            M = (np.linalg.norm(vector) * np.linalg.norm(next_vector))
            ES = np.dot(vector, next_vector)
            th = math.acos(ES / M)
            list.append(th)
            print(list)
    

    【讨论】:

      【解决方案2】:

      这里的有效解决方案是iterate over combinations of vectors

      from itertools import combinations  # At top of file
      
      for vector, next_vector in itertools.combinations(vectors, 2):
          M = (np.linalg.norm(vector) * np.linalg.norm(next_vector))
          ES = np.dot(vector, next_vector)
          th = math.acos(ES / M)
          list.append(th)
      

      它比在索引和索引上循环要快得多,降低了循环嵌套的级别,并且更清楚您要做什么(处理输入的每个唯一配对)。

      【讨论】:

        【解决方案3】:

        我不确定我是否理解您的问题,但请考虑改用范围。 范围允许您进行迭代,但不只调用确切的值,而是调用它的地址。 这意味着您可以操纵该索引来访问相邻值。

        for i in range(len(iterables)-1):
            ii = i+1
            initial_value = iterables[i]
            next_value = iterables[ii]
        
            for ii in range(len(iterables)):
                # do_rest_of_code
                                       
        

        有点像邮递员,您可以在不知道邻居地址的情况下联系到某人的邻居。
        上述结构通常有效,但您需要对其进行调整以满足您的需求。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-28
          • 2019-01-05
          • 1970-01-01
          • 2014-07-21
          • 2013-08-04
          • 1970-01-01
          相关资源
          最近更新 更多