Skip to content
189 changes: 132 additions & 57 deletions basics/trey-hunner-zip-and-enumerate.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Trey Hunner: zip and enumerate
# zip and enumerate

Now we know how [for loops](loops.md#for-loops) work in Python. But
for loops aren't limited to printing each item in a list, they can
Expand Down Expand Up @@ -75,63 +75,138 @@ b 2
c 3
>>>
```
[comment]: # (Zip and Enumerarate by Tushar starts here)
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved

Now you're ready to read [this awesome looping
tutorial](http://treyhunner.com/2016/04/how-to-loop-with-indexes-in-python/).
Read it now, then come back here and do the exercises.

## Exercises
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved

1. Create a program that works like this. Here I entered everything
after the `>` prompt that the program displayed.

```
Enter something, and press Enter without typing anything when you're done.
>hello there
>this is a test
>it seems to work
>
Line 1 is: hello there
Line 2 is: this is a test
Line 3 is: it seems to work
```

2. Create a program that prints all letters from A to Z and a to z
next to each other:

```
A a
B b
C c
...
X x
Y y
Z z
```

Start your program like this:

```python
uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
lowercase = 'abcdefghijklmnopqrstuvwxyz'
```

**Hint:** how do strings behave with `zip`? Try it out on the
`>>>` prompt and see.

3. Can you make it print the indexes also?

```
1 A a
2 B b
3 C c
...
24 X x
25 Y y
26 Z z
```

The answers are [here](answers.md).
## zip

What comes to your mind when you hear the word `zip`? A mechanism extensively used to tie two parts of something i.e. Shirt, Jacket etc. The `zip()` functions does pretty much same, it helps us tie two or more different items together.
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved

### Syntax

`zip(iterator1, iterator2, iterator3 ...) `

### Parameter Values

`zip()` can take 2 or more iterator values like so `zip(iterator1, iterator2, iterator3....)`. These
iterators will be joined together once the function is executed.

### Example 1

Let's look at an example, suppose we wish to join 2 tuples together.
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved

```python
>>> users = ("Tushar", "Aman", "Anurag", "Sohit")
uids = ("usr122", "usr123", "usr124", "usr125")
user_details = zip(uids, users)
print(user_details)
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved
>>>
<zip object at 0x149648b0d5c0>
>>>
```

If we want to get some real output we can convert this zip object into List, tuple or a set.
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved

### Example 2

```python
>>> users = ("Tushar", "Aman", "Anurag", "Sohit")
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved
uids = ("usr122", "usr123", "usr124", "usr125")
user_details = zip(uids, users)
print(list(user_details)) # converting to list
>>>
[('usr122', 'Tushar'), ('usr123', 'Aman'), ('usr124', 'Anurag'), ('usr125', 'Sohit')]
>>>
```

What if these iterators were of different lengths? well, then the ones with the extra fields will be ignored like so.
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved

### Example 3

```python
>>> users = ("Tushar", "Aman", "Anurag", "Sohit")
uids = ("usr122", "usr123", "usr124")
emails = ("tushar@example.com", "aman@example.com", "anurag@example.com", "sohit@example.com")
user_details = zip(uids, users, emails)
print(list(user_details))
>>>
[('usr122', 'Tushar', 'tushar@example.com'), ('usr123', 'Aman', 'aman@example.com'), ('usr124', 'Anurag', 'anurag@example.com')]
>>>
```

Length of `uids` is 3 thus it is the shortest tuple, now `zip()` function will crop other tuples to consider them equally and will finally join all of them together.

### Example 4: Using zip with for loop

```python
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved
>>> roll_nums = (20, 25, 28)
students = ("Joe", "Max", "Michel")
>>> for roll_num, student in zip(roll_nums, students):
... print(f"Roll number of {student} is {roll_num}")
...
Roll number of Joe is 20
Roll number of Max is 25
Roll number of Michel is 28
>>>
```

## enumerate

`enumerate()` is an amazing Built-in function offered by python. When used, gives us the index and the item combined. long story short! `enumerate` comes in handy while working with loops as it gives us access to both the item and it's index at the same time.

### Syntax

`enumerate(iterable, start=0)`

### Parameters

* Iterable: any iteration supporting object
* Start: Starting index value, default is 0

### Example 1: basic enumerate example

```python
>>> even_nums = [2, 4, 6, 8, 10, 12]
print(list(enumerate(even_nums)))
>>>
[(0, 2), (1, 4), (2, 6), (3, 8), (4, 10), (5, 12)]
>>>
```

Now before we use it in a loop let's take a look how we would do the same thing in a traditional way.

### Example 2: looping without `enumerate()`

```python
>>> even_nums = [2, 4, 6, 8, 10, 12]
>>> for index in range(0, len(even_nums)):
... print(f"Index of {even_nums[index]} is {index}")
...
Index of 2 is 0
Index of 4 is 1
Index of 6 is 2
Index of 8 is 3
Index of 10 is 4
Index of 12 is 5
>>>
```

### Example 3: looping with `enumerate()`

```python
>>> even_nums = [2, 4, 6, 8, 10, 12]
>>> for index, item in enumerate(even_nums):
... print(f"Index of {item} is {index}")
...
Index of 2 is 0
Index of 4 is 1
Index of 6 is 2
Index of 8 is 3
Index of 10 is 4
Index of 12 is 5
>>>
```

[comment]: # (Zip and Enumerarate by Tushar ends here)

***

Expand Down