You can use the zip() builtin function to iterate over two or more iterables simultaneously. In every iteration, you'll get a `tuple` with an item from each of the iterables. Here's an example:

``````>>> names = ['Joe', 'Mei', 'Rose', 'Ram']
>>> physics = [86, 91, 76, 80]
>>> maths = [77, 92, 81, 83]

>>> for n, p, m in zip(names, physics, maths):
...     print(f'{n:5}: {p},{m}')
...
Joe  : 86,77
Mei  : 91,92
Rose : 76,81
Ram  : 80,83
``````

Here are some examples using list comprehensions and generator expressions:

``````>>> p = [1, 3, 5]
>>> q = [3, 214, 53]

>>> [i + j for i, j in zip(p, q)]
[4, 217, 58]

# inner product
>>> sum(i * j for i, j in zip(p, q))
910
``````

By default, `zip()` will silently stop when the shortest iterable is exhausted:

``````>>> fruits = ('apple', 'banana', 'fig', 'guava')
>>> qty = (100, 25, 42)

>>> for f, q in zip(fruits, qty):
...     print(f'{f:6}: {q}')
...
apple : 100
banana: 25
fig   : 42
``````

The `strict` keyword argument was added in the Python 3.10 version. When set to `True`, this will raise an exception if the iterables are not of the same length:

``````>>> for f, q in zip(fruits, qty, strict=True):
...     print(f'{f:6}: {q}')
...
apple : 100
banana: 25
fig   : 42
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: zip() argument 2 is shorter than argument 1
``````

Video demo: