为什么有些语句仅适用于 manim 中 for 循环的最后一次迭代?

Why are some statements working only for the last iteration of the for loop in manim?

我正在尝试创建一个动画,我想要一个点和线列表来跟踪一个值。为此,我正在使用 ValueTracker 对象和更新程序方法。使用 ShowCreation,我已经将这些对象添加到场景中。我使用 for 循环为列表中的每个点和线添加一个更新程序(两个列表的长度相同):

 for i in range(len(x_points)):
    dots_cos[i].add_updater(
        lambda mob: mob.move_to(axes2.c2p(x_points[i], np.cos(omega.get_value()*x_points[i]))),
        # call_updater=False
        )
    dots_sin[i].add_updater(
        lambda mob: mob.move_to(axes2.c2p(x_points[i], np.sin(omega.get_value()*x_points[i]))),
        # call_updater=False
        )
    lines_cos[i].add_updater(
        lambda mob: mob.become(Line(axes2.coords_to_point(x_points[i], 0),
            axes2.coords_to_point(x_points[i], np.cos(omega.get_value()*x_points[i])), color=YELLOW)),
        # call_updater=False
        )
    lines_sin[i].add_updater(
        lambda mob: mob.become(Line(axes2.coords_to_point(x_points[i], 0),
            axes2.coords_to_point(x_points[i], np.sin(omega.get_value()*x_points[i])), color=RED)),
        # call_updater=False
        )

这没有按预期工作!发生的事情是,只有各自列表中的最后一个元素得到了更新程序,并且正常工作,而其余元素则从场景中消失了!我在 zip(x_points, dots_cos, dots_sin, lines_cos, lines_sin) 上尝试 运行 一个 for 循环,但结果仍然相同。

有趣的是,当我尝试使用 while 循环而不是循环的最后一次迭代执行相同操作时,代码尝试向最后+1 次迭代添加更新程序,因此抛出了 IndexOutOfBounds 异常。尽管像 print 语句这样的良性语句在 while 循环中运行良好。

另外,如果它很重要,点和线的列表是使用用户定义的函数生成的,returns 这些列表。

那么这里的问题是什么? add_updater 函数怎么能破坏像 for 循环这样基础的东西呢?

您遇到了一个众所周知的在循环中构造 lambda 的问题。您的解决方案可能是:

lambda mob, i=i:  ...