[英]Most efficient way to convert/unpack an itertools.chain object to an unordered and ordered list
除了使用list
和sorted
方法分别转换itertools.chain对象以获取无序列表和有序列表之外,在python3中还有更有效的方法吗? 我在此答案中看到该列表用于调试。 这是真的?
以下是我对流程进行计时的示例代码:
from itertools import chain
from time import time
def foo(n):
for i in range(n):
yield range(n)
def check(n):
# check list method
start = time()
a = list(itertools.chain.from_iterable(foo(n)))
end = time()- start
print('Time for list = ', end)
# check sorted method
start = time()
b = sorted(itertools.chain.from_iterable(foo(n)))
end = time()- start
print('Time for sorted = ', end)
结果:
>>> check(1000)
Time for list = 0.04650092124938965
Time for sorted = 0.08582258224487305
>>> check(10000)
Time for list = 1.615750789642334
Time for sorted = 8.84056806564331
>>>
最有效的方法是使用list()
但是如果您想通过itertools.chain()
展平嵌套的iterable或将某些iterables连接起来,然后将其转换为list,则可以立即使用嵌套的list comprehension。 同样, sorted()
花费更多时间的原因是,它对可迭代对象进行排序,而list只是调用了一些生成器函数的方法(例如__next__
),以便将项目复制到list对象。
请注意,就运行时间而言, itertools.chain
执行速度甚至比列表理解(python 2.x和python 3.x)还要快。 这是一个例子:
In [27]: lst = [range(10000) for _ in range(10000)]
In [28]: %timeit [i for sub in lst for i in sub]
1 loops, best of 3: 3.94 s per loop
In [29]: %timeit list(chain.from_iterable(lst))
1 loops, best of 3: 2.75 s per loop
除了使用list和sorted方法分别转换itertools.chain对象以获取无序列表和有序列表之外,在python3中还有更有效的方法吗?
简单的回答:不。 使用python生成器和迭代器时,唯一需要避免的警告是将生成器转换为列表,然后转换为生成器,然后再次转换为列表,等等。
即像这样的一条链是愚蠢的:
list(sorted(list(filter(list(map(…
因为您将失去所有发电机的附加值。
我在此答案中看到该列表用于调试。 这是真的?
它取决于您的上下文,通常来说list()
不是用于调试的,这是表示可迭代对象的另一种方式。
如果需要访问给定索引处的元素,或者想知道数据集的长度,则可能要使用list()
。 如果您可以随时使用数据,则不希望使用list()
。
可以将所有生成器/迭代器方案视为对可用的每一项应用算法的一种方法,而您要大量处理列表。
关于您引用的问题,这个问题非常具体,它询问如何从REPL内省一个生成器,以便了解其中的内容。 回答此问题的人的建议是仅将list(chain)
用于自省,但应保持原来的状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.