在我的看来,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 的理由是什么呢?
在我的看来,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 的理由是什么呢?
针对你提出的这两个例子:
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提到的那样,使用迭代器时不能使用括号切片或加法。
我希望这已经足够回答了,还有很多其他答案和资源解释为什么迭代器很棒,所以我不想在这里重复所有的信息。
itertools.chain
可以接受多个参数,将任意数量的列表链接在一起,而使用 +
运算符则无法实现。例如:itertools.chain(*arbitrary_list_of_lists)
。 - veggie1+
来连接多个列表。不过最好还是使用itertools.chain()
,或者如果需要存储的话,可以使用list.extend()
来构建一个列表。 - Cyphaseoperator.add
的循环,否则不能为任意或未知数量的列表执行此操作。 - veggie1sum(([1, 2, 3], [4, 5, 6], [7, 8, 9]), [])
。或者,sum(arbitrary_list_of_lists, [])
。 :D - Cyphasesum
这个函数做那件事。谢谢! - veggie1islice
也不会创建新的列表,而常规的列表切片则会。 - BrenBarnislice
将在列表中迭代通过0..start
元素,而列表切片跳过它们并直接到达start
。也许一个替代方案是(xs[i] for i in range(start, stop))
。 - Mateen Ulhaq你可以使用原生的Python来完成它
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]