<jupyter_start><jupyter_text>Laziness*加速工作的效率和规模化*<jupyter_code># We build a somewhat large list of integers

integers = range(10000000)<jupyter_output><empty_output><jupyter_text>这是10,000,000个数字。 不是很大，但也不小。 我们需要小心，这些整数需要蛮大的资源代价。素数计算测试是昂贵的。 让我们来做！<jupyter_code>import sympy # don't worry if you don't have this
from toolz import filter
primes = filter(sympy.isprime, integers)<jupyter_output><empty_output><jupyter_text>Q: *我认为测试素数计算是相当昂贵的。 为什么这么快就回来？A: The `toolz.filter` is lazy.  没有进行实际的工作。<jupyter_code>primes  # not actually a list of primes<jupyter_output><empty_output><jupyter_text>然而，我们仍然可以将变量primes看作一个素数列表。 让我们打印前几个<jupyter_code>next(primes)
next(primes)
next(primes)
# Note that primes is not a list like integers.  We can't index into it

primes[1000] # 1000th prime please
# But we *can* still iterate over it

for p in primes:
    print(p)
    if p > 100:  # stop us from going through the whole list
        break<jupyter_output>109<jupyter_text>请注意，前几个素数2，3，5不包含在此列表中。 惰性迭代器中的项目在使用时消耗，永远不会再被看到。 如果你真的想存储迭代器，那就调用它的`list`构造函数<jupyter_code>primes = list(primes)  # fully evaluate the lazy iterator, store it in a list<jupyter_output><empty_output><jupyter_text>Infinite iterators懒惰执行可以理解为 我们在谈工作，而没有真正在做它。 这种与现实的分离开辟了新的可能性。 例如，这里是所有斐波那契数字<jupyter_code>def fib():
    """ A generator for all Fibonacci numbers """
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

fibs = fib()  # make a lazy iterator, fibs
print(next(fibs))
print(next(fibs))
print(next(fibs))
print(next(fibs))

fibs[100]<jupyter_output><empty_output><jupyter_text>Toolz functionsToolz提供了与惰性迭代器交互的函数。<jupyter_code>from toolz import first, second, nth, drop, take
first(fib())
second(fib())
nth(100, fib())
take(20, fib())  # Yet another iterator
list(take(20, fib()))  # But this one is finite, so we can expand it with list
later_fibs = drop(100, fib())
next(later_fibs)
# These all depend on itertools.islice
from itertools import islice
list(islice(fib(), 10, 20, 2))  # fib()[10:20:1]<jupyter_output><empty_output><jupyter_text>示例：将函数应用于文本Python文件对象是一个懒惰的迭代器。 当我打开一个大的文本文件时，Python实际上并没有一次读入所有的文本。<jupyter_code>book = open('data/tale-of-two-cities.txt')<jupyter_output><empty_output><jupyter_text>Each element of the book is a line of text.<jupyter_code>print(1, next(book))
print(2, next(book))
print(3, next(book))
print(4, next(book))<jupyter_output>1 锘縏he Project Gutenberg EBook of A Tale of Two Cities, by <NAME>

2 

3 This eBook is for the use of anyone anywhere at no cost and with

4 almost no restrictions whatsoever.  You may copy it, give it away or<jupyter_text>这是书Gutenberg的标题。 这大概是112行。 让我们开始翻书，然后放下标题。<jupyter_code>book = open('data/tale-of-two-cities.txt')
book = drop(112, book)
next(book)<jupyter_output><empty_output><jupyter_text>这看起来很熟悉。 让我们从所有的行中删除 `\r\n`<jupyter_code>from toolz import map  # toolz.map is lazy too
book = map(str.strip, book)
next(book)<jupyter_output><empty_output><jupyter_text>在语义上，就好像我们将“str.strip”应用于书中的每一行实际上我们没有做任何工作。相反，`map`返回了一个新的惰性迭代器，它从原始的`book`中绘制一个元素，应用`str.strip`，然后得到结果。 只有当我们要求时才这样做。 我们可以将懒惰操作链接在一起。 剥去每一行后，我们将把重点放在那些包含单词“Mr.” 的行上，或带有 “Miss” 和 "Mrs."<jupyter_code>def good_line(line):
    return "Mr." in line or "Miss" in line or "Mrs." in line

book = filter(good_line, book)
next(book)
# Lets take 10 lines from this iterator and display them

for line in take(10, book):
    print(1, line)<jupyter_output>1 "I know this messenger, guard," said <NAME>, getting down into the
1 like a larger dog-kennel. Mr. Lorry, the passenger, shaking himself out
1 Mr. Lorry dropped off to sleep. The arrival of his breakfast roused him,
1 time to-day. She may ask for Mr. <NAME>, or she may only ask for a
1 When Mr. Lorry had finished his breakfast, he went out for a stroll on
1 again charged with mist and vapour, Mr. Lorry's thoughts seemed to cloud
1 Mr. Lorry had been idle a long time, and had just poured out his last
1 In a very few minutes the waiter came in to announce that Miss Manette
1 Miss Manette had taken some refreshment on the road, and required none
1 wig at the ears, and follow the waiter to Miss Manette's apartment.
{'fraction_non_alphanumeric': 0.10400390625, 'fraction_numerical': 0.021240234375, 'mean_word_length': 5.991467576791809, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 50, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '86358', 'license': 'MIT', 'n_tokens_mistral': 1905, 'n_tokens_neox': 1861, 'n_words': 443, 'path': '5-laziness.ipynb', 'repo_name': 'PyDriven/pydata-toolz', 'size': '4114'}