繁体   English   中英

将itertools.chain对象转换/解压缩为无序列表的最有效方法

[英]Most efficient way to convert/unpack an itertools.chain object to an unordered and ordered list

除了使用listsorted方法分别转换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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM