除了使用list
和sorted
方法转换itertools.chain对象以分别得到无序和有序列表之外,还有更有效的方法在python3中做同样的事情吗?我在这个answer中读到该列表用于调试。这是真的吗?
下面是我为进程计时的示例代码:
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
>>>
答案 0 :(得分:1)
最有效的方法是使用list()
,但是如果你想通过itertools.chain()
展平嵌套迭代或连接一些迭代,然后将它转换为列表,你可以立即使用嵌套列表理解。 sorted()
花费更多时间的原因是它对iterable进行排序,而list只调用生成器函数的某些方法(如__next__
),以便将项目复制到列表对象。
请注意,就运行时而言,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
答案 1 :(得分:1)
答案很简单:没有。使用python生成器和迭代器时,唯一需要注意的是将生成器转换为列表,然后转换为生成器,然后再转换为列表等等......除了使用list和sorted方法将itertools.chain对象转换成无序和有序列表之外,还有更有效的方法在python3中做同样的事情吗?
即。像这样的连锁店是愚蠢的:
list(sorted(list(filter(list(map(…
因为你会失去发电机的所有附加价值。
我在这个答案中读到该列表用于调试。这是真的?
这取决于你的上下文,一般来说list()
不是用于调试,它是表示可迭代的不同方式。
如果您需要访问给定索引处的元素,或者您想知道数据集的长度,则可能需要使用list()
。
如果您可以随时使用数据,则不希望使用list()
。
将所有生成器/迭代器方案视为在每个项目可用时应用算法的方法,而将列表作为批量处理。
关于你引用的问题,问题是非常具体的,它询问如何从REPL内省发电机,以了解内部的内容。回答这个问题的人的建议是仅使用list(chain)
进行内省,但保留最初的内容。