What Is zip() Function In Python
Tags: python, programming, tutorial, functions
Published: 2023-06-06 06:55:44

***Have you ever heard the word "parallel iteration" or tried to "loop over multiple iterables in parallel" when you were coding in Python?***

This tutorial will show a Python `zip()` function that helps us perform a **parallel iteration over multiple iterables**.

## Definition

`zip()` function takes iterables and iterates over them parallelly, which results in producing tuples of each item from the iterables.

```python
items = ["Computer", "Keyboard", "CPU", "Mouse"]
units = [3, 2, 4, 6]

mapping = zip(items, units)

print(tuple(mapping))
```

**Output**

```bash
(('Computer', 3), ('Keyboard', 2), ('CPU', 4), ('Mouse', 6))
```

In other words, it returns the **iterator of tuples** where the **first item in each passed iterator is paired together** and then the **second item in each passed iterator is paired together** and it **goes so on until the shortest iterator is exhausted**.

> Another way to think of `zip()` is that it turns rows into columns and columns into rows. This is similar to transposing a matrix.[Source](https://docs.python.org/3/library/functions.html#zip)

## Syntax

The syntax of Python `zip()` function is:

`zip(*iterables)` or `zip(iterator1, iterator2, ...)`

**In Python 3.10, the** `strict` **argument was added**

`zip(*iterables, strict=False)`

We'll see the use of `strict` ahead in this tutorial.

`zip()` **parameters:**

`iterables`: they can be lists, tuples, dictionaries, or objects that can be iterated.

## Example

```python
languages = ["Python", "JavaScript", "C", "C++"]
founded = [1991, 1995, 1972, 1985]

mapping = zip(languages, founded)

print(list(mapping))

print(type(list(mapping)))
```

**Output**

```bash
[('Python', 1991), ('JavaScript', 1995), ('C', 1972), ('C++', 1985)]
<class 'list'>
```

## Working of zip() function

How `zip()` function creates an iterator of the tuple?

We can actually say that zipping means aggregating two separate things into one.

Just like it, the **Python** `zip()` **function works by taking two inputs say** `A1` **and** `A2`, **and then aggregating the item of the same index number of** `A1` **and** `A2`.

We will better understand through the illustration below


![zip function working](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5dt3w9jnn7icp6k7zhjd.png)

* We can clearly see, on the right side - the tuple at the 0th index contains each item of `A1` and `A2` at the 0th index respectively.
    
* The same goes for items at the 1st index of `A1` and `A2`.
    
* In general, the tuple at the index `i` contains items at the index `i` in `A1` and `A2`.
    

***More formally: zip() returns an iterator of tuples, where the i-th tuple contains the i-th element from each of the argument iterables.***[***Source***](https://docs.python.org/3/library/functions.html#zip)

## Iterables of different lengths

What happens if iterables are of different lengths?

Nothing's gonna happen if the iterables passed to the `zip()` function have different lengths because **if we refer to official Python docs then it states that *"the iterator stops when the shortest iterable is exhausted"*.**

**Example**

```python
languages = ["Python", "JavaScript", "C", "C++"]
founded = [1991, 1995, 1972]

mapping = zip(languages, founded)

print(list(mapping))
```

**Output**

```bash
[('Python', 1991), ('JavaScript', 1995), ('C', 1972)]
```

Here, the `C++` was excluded because the `founded` variable contains only three arguments.

### What if Python throws an error when the iterables are of different lengths?

Let's understand with an example

```python
languages = ["Python", "JavaScript", "C", "C++"]
founded = [1991, 1995, 1972]

mapping = zip(languages, founded, strict=True)

print(list(mapping))
```

**Output**

```bash
Traceback (most recent call last):
  ....
ValueError: zip() argument 2 is shorter than argument 1
```

Did you notice that there is an additional argument `strict=True` in the code?

The `strict` argument is added in **Python version 3.10**

If the iterables have different lengths and we use the `strict` argument, the code will throw a `ValueError`. It can be useful for debugging.

## Passing one or no iterable to the zip()

**The** `zip()` **function will return an empty iterator if no parameters were passed.**

```python
no_iterable = zip()
print(list(no_iterable))
```

**Output**

```bash
[]
```

**If we pass only one iterable, then the** `zip()` **function will return an iterator of tuples each having only one element.**

```python
languages = ["Python", "JavaScript", "C", "C++"]

mapping = zip(languages)

print(list(mapping))
```

**Output**

```bash
[('Python',), ('JavaScript',), ('C',), ('C++',)]
```

## Python zip() Examples

**Example: Using** [**enumerate()**](https://geekpython.in/python-enumerate-function-with-example-beginner-s-guide) **function with zip()**

```python
characters = ["Iron Man", "Thor", "Spiderman"]
real_names = ["RDJ", "Chris Hemsworth", "Andrew Garfield"]

result = zip(characters, real_names)

for num, results in enumerate(result):
    print(num, results)
```

**Output**

```bash
0 ('Iron Man', 'RDJ')
1 ('Thor', 'Chris Hemsworth')
2 ('Spiderman', 'Andrew Garfield')
```

**Example: Using range() function**

```python
name = ["Sachin", "Rishu", "Yashwant", "Abhishek"]

values = zip(range(4), name)

print(tuple(values))
```

**Output**

```python
((0, 'Sachin'), (1, 'Rishu'), (2, 'Yashwant'), (3, 'Abhishek'))
```

**Example: Having multiple iterables**

```python
characters = ["Iron Man", "Thor", "Spiderman"]
real_names = ["RDJ", "Chris Hemsworth", "Andrew Garfield"]
reel_names = ["Tony Stark", "Thor", "Peter Parker"]

result = zip(characters, real_names, reel_names)

print(list(result))
```

**Output**

```python
[('Iron Man', 'RDJ', 'Tony Stark'), ('Thor', 'Chris Hemsworth', 'Thor'), ('Spiderman', 'Andrew Garfield', 'Peter Parker')]
```

**Example: Typecasting into different data types**

**Typecasting into List**

```python
characters = ["Iron Man", "Thor", "Spiderman"]
real_names = ["RDJ", "Chris Hemsworth", "Andrew Garfield"]

result = zip(characters, real_names)

print(f"List: {list(result)} and type is {type(list(result))}")
```

**Output**

```bash
List: [('Iron Man', 'RDJ'), ('Thor', 'Chris Hemsworth'), ('Spiderman', 'Andrew Garfield')] and type is <class 'list'>
```

**Typecasting into Dictionary**

```python
characters = ["Iron Man", "Thor", "Spiderman"]
real_names = ["RDJ", "Chris Hemsworth", "Andrew Garfield"]

result = zip(characters, real_names)

print(f"Dictionary: {dict(result)} and type is {type(dict(result))}")
```

**Output**

```bash
Dictionary: {'Iron Man': 'RDJ', 'Thor': 'Chris Hemsworth', 'Spiderman': 'Andrew Garfield'} and type is <class 'dict'>
```

**Typecasting into Set**

```python
characters = ["Iron Man", "Thor", "Spiderman"]
real_names = ["RDJ", "Chris Hemsworth", "Andrew Garfield"]

result = zip(characters, real_names)

print(f"Set: {set(result)} and type is {type(set(result))}")
```

**Output**

```bash
Set: {('Iron Man', 'RDJ'), ('Spiderman', 'Andrew Garfield'), ('Thor', 'Chris Hemsworth')} and type is <class 'set'>
```

**Typecasting into Tuple**

```python
characters = ["Iron Man", "Thor", "Spiderman"]
real_names = ["RDJ", "Chris Hemsworth", "Andrew Garfield"]

result = zip(characters, real_names)

print(f"Tuple: {tuple(result)} and type is {type(tuple(result))}")
```

**Output**

```bash
Tuple: (('Iron Man', 'RDJ'), ('Thor', 'Chris Hemsworth'), ('Spiderman', 'Andrew Garfield')) and type is <class 'tuple'>
```

## Unzipping the Values

We can actually **unzip the values** that were **already zipped**. Let's see how to do so.

This can be done with the help of `*` [asterisk operator](https://geekpython.in/asterisk-in-python).

Let's understand with an example.

```python
characters = ["Iron Man", "Thor", "Spiderman"]
real_names = ["RDJ", "Chris Hemsworth", "Andrew Garfield"]
reel_names = ["Tony Stark", "Thor", "Peter Parker"]

mapping = zip(characters, real_names, reel_names)

mapped = list(mapping)

print(f"Zipped result: {mapped}", end="")

print("\n")

# unzipping values
char, real, reel = zip(*mapped)

print("Unzipped result:")

print(f"The characters list is : {char}")

print(f"The real_names list is : {real}")

print(f"The reel_names list is : {reel}")
```

**Output**

```bash
Zipped result: [('Iron Man', 'RDJ', 'Tony Stark'), ('Thor', 'Chris Hemsworth', 'Thor'), ('Spiderman', 'Andrew Garfield', 'Peter Parker')]

Unzipped result:
The characters list is : ('Iron Man', 'Thor', 'Spiderman')
The real_names list is : ('RDJ', 'Chris Hemsworth', 'Andrew Garfield')
The reel_names list is : ('Tony Stark', 'Thor', 'Peter Parker')
```

Notice how we unzipped the values of the variable `mapped` using `*` and to store the unzipped values we declared three variables `char`, `real` and `reel`

## Conclusion

In this tutorial, you've learned to perform a parallel iteration using Python's `zip()` function and I hope you understand how to use it.

You now understand how the `zip()` function works behind the scenes to generate a tuple iterator.

Try the code snippets written above in your IDEs to understand the code better.

---

🏆**Other articles you might be interested in if you liked this one**

✅[How to convert bytes into strings in Python](https://geekpython.in/convert-bytes-into-string)?

✅[f-string: An improved and modern way of string formatting](https://geekpython.in/f-string-in-python).

✅[How to access the list values within the dictionary in Python](https://geekpython.in/access-list-values-within-the-dictionary)?

✅[How to use \_\_str\_\_ and \_\_repr\_\_ to change the string representation of the objects in Python](https://geekpython.in/str-and-repr-in-python)?

✅[How do sort() and sorted() functions are different from each other](https://geekpython.in/python-sort-vs-sorted)?

✅[What is the difference between seek() and tell() in Python](https://geekpython.in/seek-and-tell-in-python)?

✅[How to use tempfile module to create temporary files and dirs in Python](https://geekpython.in/tempfile-in-python)?

---

**That's all for now.**

**Keep Coding✌✌**