为什么我要使用itertools.islice而不是正常的列表切片?

时间:2015-08-23 23:37:26

标签: python list iterator

在我看来,itertools模块中的许多函数都具有更容易的等价物。例如,据我所知,itertools.islice(range(10),2,5)range(10)[2:5]的功能相同,而itertools.chain([1,2,3],[4,5,6])[1,2,3]+[4,5,6]的功能相同。主文档页面提到了速度优势,但除此之外还有任何理由选择itertools吗?

3 个答案:

答案 0 :(得分:18)

要解决你提出的两个例子:

import itertools


data1 = range(10)

# This creates a NEW list
data1[2:5]

# This creates an iterator that iterates over the EXISTING list
itertools.islice(data1, 2, 5)


data2 = [1, 2, 3]
data3 = [4, 5, 6]

# This creates a NEW list
data2 + data3

# This creates an iterator that iterates over the EXISTING lists
itertools.chain(data2, data3)

您有多少理由想要使用迭代器而不是其他方法。如果列表非常大,则创建包含大型子列表的新列表可能会出现问题,或者尤其是创建包含两个其他列表副本的列表。使用islice()chain()允许您以您希望的方式迭代列表,而无需使用更多内存或计算来创建新列表。另外,正如unutbu所述,您不能使用括号切片或添加迭代器。

我希望这个答案足够;有很多其他答案和其他资源解释为什么迭代器很棒,所以我不想在这里重复所有这些信息。

答案 1 :(得分:17)

itertools.islice可以切片iterators。 索引仅适用于sequences。 例如,

In [64]: iterator = (x**2 for x in range(10))

In [65]: list(IT.islice(iterator, 2, 5))
Out[65]: [4, 9, 16]

In [66]: iterator[2:5]
TypeError: 'generator' object has no attribute '__getitem__'

答案 2 :(得分:0)

你可以用香草蟒来做

In [64]: iterator = (x**2 for x in range(10))

In [65]: [x for i, x in enumerate(iterator) if i>=2 and i<5]
Out[65]: [4, 9, 16]