Skip to content
139 changes: 80 additions & 59 deletions basics/trey-hunner-zip-and-enumerate.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,71 +75,49 @@ b 2
c 3
>>>
```
[comment]: # (Zip and Enumerarate by Tushar starts here)

## 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.

```python
>>> users = ("Tushar", "Aman", "Anurag", "Sohit")
uids = ("usr122", "usr123", "usr124", "usr125")
user_details = zip(uids, users)
print(user_details)
>>>
<zip object at 0x149648b0d5c0>
>>> users = ["Tushar", "Aman", "Anurag", "Sohit"]
>>> uids = ["usr122", "usr123", "usr124", "usr125"]
>>> user_details = zip(uids, users)
>>> print(user_details)
<zip object at 0x0000016938E311C0>
>>>
```

If we want to get some real output we can convert this zip object into List, tuple or a set.

### Example 2
After calling zip, an iterator is returned. In order to see the content wrapped inside, we need to first convert it to a list. Basically, `zip()` is an iterator, i.e. lazy: it gives the items as needed, instead of calculating them and storing them into memory all at once. So the zip object cannot show its elements before the elements are used, because it hasn't computed them yet.
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(list(user_details)) # converting to list
>>>
>>> users = ["Tushar", "Aman", "Anurag", "Sohit"]
>>> uids = ["usr122", "usr123", "usr124", "usr125"]
>>> user_details = zip(uids, users)
>>> print(list(user_details))
[('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.

### Example 3
If the lists are of different lengths, some items from the end of the longer list will be ignored.

```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')]
>>> users = ["Tushar", "Aman", "Anurag", "Sohit"]
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved
>>> emails = ["tushar@example.com", "aman@example.com", "anurag@example.com", "sohit@example.com"]
>>> users_contact = zip(users, emails)
>>> print(list(users_contact))
[('Tushar', 'tushar@example.com'), ('Aman', 'aman@example.com'), ('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.
Length of `users` list is 3 thus it is the shortest. `zip()` function will crop other lists to consider them equally and will finally join all items together.
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved

### Example 4: Using zip with for loop
### Using zip with for loop
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved

```python
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved
>>> roll_nums = (20, 25, 28)
students = ("Joe", "Max", "Michel")
>>> 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}")
...
Expand All @@ -153,28 +131,16 @@ Roll number of Michel is 28

`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)))
>>>
>>> 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.
Before we use it in a loop let's take a look how we would do the same thing in a traditional way.
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved

### Example 2: looping without `enumerate()`
### looping without `enumerate()`
Comment thread
tusharkhatriofficial marked this conversation as resolved.
Resolved

```python
>>> even_nums = [2, 4, 6, 8, 10, 12]
Expand All @@ -190,7 +156,7 @@ Index of 12 is 5
>>>
```

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

```python
>>> even_nums = [2, 4, 6, 8, 10, 12]
Expand All @@ -206,7 +172,62 @@ Index of 12 is 5
>>>
```

[comment]: # (Zip and Enumerarate by Tushar ends here)
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.

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

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).

***

Expand Down