I have a question regarding this piece of code, which transforms the elements of TexMobject (for example, element 2 is transformed to 8, 3 is transformed to 9 and so on):
changes = [
[(2,4,3), (8,11,9)],
[(0,0), (7,10)]
]
for pre_ind, post_ind in changes:
self.play(
*[
ReplacementTransform(formula[i].copy(), formula[j])
for i,j in zip(pre_ind, post_ind)
]
)
self.wait()
self.wait()
I see that there is a list comprehension used to generate indices pairs, but I don't understand why is there an args asterisk (*) before the square brackets in self.play()
? What is the purpose of using *args notation in this case, if list comprehension works without it?
You have to understand a couple of concepts before:
self.play()
refers to Scene.play()
, because we know that self
refers to the class being defined.class.method(*args,**kwargs)
, orclass.method(*args_1, *args_2, *args_3, ..., *args_n,**kwargs_1, **kwargs_2, ..., **kwargs_m)
Where args
is a LIST/TUPLA and kwargs
is a dictionary. In this case, Scene.play
is used like this:
Scene.play(Animation1(...), Animation2(...), ..., **kwargs)
# Example:
Scene.play(Write(mob1), Write(mob2), run_time=4)
# But, this is the same as:
Scene.play(*[Write(mob1), Write(mob2)], run_time=4)
# Or better:
Scene.play(*[Write(mobs) for mobs in [mob1,mob2]], run_time=4)
I suppose (you didn't make it very clear) that you are referring to why you can't do something like:
Scene.play([ReplacementTransform(...) for _ in ...])
or
Scene.play(ReplacementTransform(...) for _ in ...)
Intuitively we can understand that this is a syntax error, because the Python interpreter will not be able to understand the parameters that are being given, remember that this is NOT the way to use a method.
The operator *
is called "spread operator", what it does is "take out" all the elements that are in a list. More information here.