Skip to content

Commit 4d5a2f0

Browse files
committed
New example: Lossy zip of iterators
Resolves satwikkansal#121
1 parent bf967b0 commit 4d5a2f0

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,55 @@ I've lost faith in truth!
12511251
12521252
---
12531253
1254+
### ▶ Lossy zip of iterators
1255+
1256+
```py
1257+
>>> numbers = list(range(7))
1258+
>>> numbers
1259+
[0, 1, 2, 3, 4, 5, 6]
1260+
>>> first_three, remaining = numbers[:3], numbers[3:]
1261+
>>> first_three, remaining
1262+
([0, 1, 2], [3, 4, 5, 6])
1263+
>>> numbers_iter = iter(numbers)
1264+
>>> list(zip(numbers_iter, first_three))
1265+
[(0, 0), (1, 1), (2, 2)]
1266+
# so far so good, let's zip the remaining
1267+
>>> list(zip(numbers_iter, remaining))
1268+
[(4, 3), (5, 4), (6, 5)]
1269+
```
1270+
Where did element `3` go from the `numbers` list?
1271+
1272+
#### 💡 Explanation:
1273+
1274+
- From Python [docs](https://docs.python.org/3.3/library/functions.html#zip), here's an approximate implementation of zip function,
1275+
```py
1276+
def zip(*iterables):
1277+
sentinel = object()
1278+
iterators = [iter(it) for it in iterables]
1279+
while iterators:
1280+
result = []
1281+
for it in iterators:
1282+
elem = next(it, sentinel)
1283+
if elem is sentinel:
1284+
return
1285+
result.append(elem)
1286+
yield tuple(result)
1287+
```
1288+
- So the function takes in arbitrary number of itreable objects, adds each of their items to the `result` list by calling the `next` function on them, and stops whenever any of the iterable is exhausted.
1289+
- The caveat here is when any iterable is exhausted, the existing elements in the `result` list are discarded. That's what happened with `3` in the `numbers_iter`.
1290+
- The correct way to do the above using `zip` would be,
1291+
```py
1292+
>>> numbers = list(range(7))
1293+
>>> numbers_iter = iter(numbers)
1294+
>>> list(zip(first_three, numbers_iter))
1295+
[(0, 0), (1, 1), (2, 2)]
1296+
>>> list(zip(remaining, numbers_iter))
1297+
[(3, 3), (4, 4), (5, 5), (6, 6)]
1298+
```
1299+
The first argument of zip should be the one with fewest elements.
1300+
1301+
---
1302+
12541303
### ▶ From filled to None in one instruction...
12551304
12561305
```py

0 commit comments

Comments
 (0)