itertools.count 和 itertools.islice 的意义是什么?

but*_*ife 2 python python-itertools

我看过在线课程,他们有如下示例:

from itertools import count
  
# creates a count iterator object
iterator =(count(start = 0, step = 2))
  
# prints an even list of integers
print("Even list:", 
      list(next(iterator) for _ in range(5)))
Run Code Online (Sandbox Code Playgroud)

...您可以使用range或 来编写np.arange。这是另一个例子:

# list containing some strings
my_list =["x", "y", "z"]
  
# count spits out integers for 
# each value in my list
for i in zip(count(start = 1, step = 1), my_list):
    print(i)
Run Code Online (Sandbox Code Playgroud)

...这基本上只是enumerate。所以我的问题是:您能否举一个使用 无法完成(或必须更加笨拙地完成)的itertools.count示例?itertools.islicerange

che*_*ner 6

在这种情况下,count实例是偶尔使用的,而不是在单个循环中立即使用。

class Foo:
    _x = count()  # Infinite supply of unique integer values

    def __init__(self):
        self._id = f'Foo #{next(self._x)}'
Run Code Online (Sandbox Code Playgroud)

islice这是一个用于防止 O(n) 内存使用的情况:

def is_sorted(some_list):
    return all(i <= j for i, j in zip(some_list, islice(some_list, 1, None)))
Run Code Online (Sandbox Code Playgroud)

如果你把它写成

def is_sorted(some_list):
    return all(i <= j for i, j in zip(some_list, some_list[1:]))
Run Code Online (Sandbox Code Playgroud)

在测试第一对之前,您将不得不制作几乎完整的副本some_list,这对于像[2, 1] + [3] * 10000.


两者都不是必要的,因为每一个都是可以简单定义的:

def count(start=0, step=1):
    while True:
        yield start
        start += step

# A more accurate translation would be more complicated than necessary for our purposes here.
# The real version would have to be able to handle stop=None
# and choose 1 and -1 as default values for step, depending
# on whether stop is less than or greater than start.
def islice(itr, start, stop, step):
    for _ in range(start):
        next(itr)

    while start < stop:
        yield next(itr)
        start += step
Run Code Online (Sandbox Code Playgroud)