Skip to content

Commit 155285e

Browse files
committed
EX.Lossy zip of iterators
1 parent fbe5bba commit 155285e

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ PS: 如果你不是第一次读了, 你可以在[这里](https://github.com/satw
6969
- [> Modifying a dictionary while iterating over it/迭代字典时的修改](#-modifying-a-dictionary-while-iterating-over-it迭代字典时的修改)
7070
- [> Stubborn `del` operator/坚强的 `del` *](#-stubborn-del-operator坚强的-del-)
7171
- [> Deleting a list item while iterating/迭代列表时删除元素](#-deleting-a-list-item-while-iterating迭代列表时删除元素)
72+
- [> Lossy zip of iterators/丢三落四的zip *](#->-Lossy-zip-of-iterators/丢三落四的zip-)
7273
- [> Loop variables leaking out!/循环变量泄漏!](#-loop-variables-leaking-out循环变量泄漏)
7374
- [> Beware of default mutable arguments!/当心默认的可变参数!](#-beware-of-default-mutable-arguments当心默认的可变参数)
7475
- [> Catching the Exceptions/捕获异常](#-catching-the-exceptions捕获异常)
@@ -1974,6 +1975,62 @@ for idx, item in enumerate(list_4):
19741975
* 参考这个StackOverflow的[回答](https://stackoverflow.com/questions/45946228/what-happens-when-you-try-to-delete-a-list-element-while-iterating-over-it)来解释这个例子
19751976
* 关于Python中字典的类似例子, 可以参考这个Stackoverflow的[回答](https://stackoverflow.com/questions/45877614/how-to-change-all-the-dictionary-keys-in-a-for-loop-with-d-items).
19761977

1978+
1979+
---
1980+
1981+
### > Lossy zip of iterators/丢三落四的zip *
1982+
<!-- Example ID: c28ed154-e59f-4070-8eb6-8967a4acac6d --->
1983+
1984+
```py
1985+
>>> numbers = list(range(7))
1986+
>>> numbers
1987+
[0, 1, 2, 3, 4, 5, 6]
1988+
>>> first_three, remaining = numbers[:3], numbers[3:]
1989+
>>> first_three, remaining
1990+
([0, 1, 2], [3, 4, 5, 6])
1991+
>>> numbers_iter = iter(numbers)
1992+
>>> list(zip(numbers_iter, first_three))
1993+
[(0, 0), (1, 1), (2, 2)]
1994+
# so far so good, let's zip the remaining
1995+
>>> list(zip(numbers_iter, remaining))
1996+
[(4, 3), (5, 4), (6, 5)]
1997+
```
1998+
1999+
`numbers` 列表中的元素 `3` 哪里去了?
2000+
2001+
#### 💡 说明
2002+
2003+
- 根据Python [文档](https://docs.python.org/3.3/library/functions.html#zip)`zip` 函数的大概实现如下:
2004+
2005+
```py
2006+
def zip(*iterables):
2007+
sentinel = object()
2008+
iterators = [iter(it) for it in iterables]
2009+
while iterators:
2010+
result = []
2011+
for it in iterators:
2012+
elem = next(it, sentinel)
2013+
if elem is sentinel: return
2014+
result.append(elem)
2015+
yield tuple(result)
2016+
```
2017+
2018+
- 该函数接受任意数量的可迭代对象,通过调用 `next` 函数将它们的每个项目添加到 `result` 列表中,并在任一可迭代对象耗尽时停止。
2019+
- 这里需要注意的是,当任一可迭代对象用尽时,`result` 列表中的现有元素将被丢弃。这就是 `numbers_iter` 中的 `3` 所发生的情况。
2020+
- 使用 zip 执行上述操作的正确方法是:
2021+
2022+
```py
2023+
>>> numbers = list(range(7))
2024+
>>> numbers_iter = iter(numbers)
2025+
>>> list(zip(first_three, numbers_iter))
2026+
[(0, 0), (1, 1), (2, 2)]
2027+
>>> list(zip(remaining, numbers_iter))
2028+
[(3, 3), (4, 4), (5, 5), (6, 6)]
2029+
```
2030+
2031+
`zip` 的第一个参数应当是有最少元素的那个。
2032+
2033+
19772034
---
19782035

19792036
### > Loop variables leaking out!/循环变量泄漏!

0 commit comments

Comments
 (0)