Crack open the python shell and experiment. First, there is what is being returned by zip
:
>>> listFrench = ['un', 'deux', 'trois', 'quatre', 'cinq']
>>> listEnglish = ['one', 'two', 'three', 'four', 'five']
>>> for x in zip(listFrench, listEnglish):
... print(x)
...
('un', 'one')
('deux', 'two')
('trois', 'three')
('quatre', 'four')
('cinq', 'five')
zip
is returning tuples, each with 2 values in it. In fact, its yielding items from each input list. It can take any number of input lists (anything iterable, really) and returns tuples from each item in the lists in turn.
Now, lets see what happens with that first tuple
>>> wF, wE = ('un', 'one')
>>> wF
'un'
>>> wE
'one'
That's tuple unpacking. We have two variables on the left hand side and a tuple with two elements on the right. So, python assigned the variable.
Finally, that "f" is for Augmented String Interpolation. It lets you format a string from data already defined in your program.
>>> f"The French word for {wE} is {wF}"
'The French word for one is un'