【问题标题】:Best way to directly generate a sublist from a python iterator从 python 迭代器直接生成子列表的最佳方法
【发布时间】:2020-05-02 20:30:39
【问题描述】:

It is easy to convert an entire iterator sequence into a list 使用list(iterator),但是在不首先创建整个列表的情况下直接从迭代器创建子列表的最佳/最快方法是什么,即如何在不首先创建整个列表的情况下最好地创建list(iterator)[m:n]

很明显,对于m > 0,它不应该*(至少不总是)可以直接这样做,但对于n,它应该小于序列的长度。想到[p for i,p in zip(range(n), iterator)],但这是最好的方法吗?

上下文很简单:创建整个列表会导致 RAM 溢出,因此需要对其进行分解。那么你如何有效地和/或 python-ic-ly 做到这一点?


*我提到的列表理解显然可以用于m > 0,方法是在执行前调用next(iterator)m 次,但我不喜欢这里缺少python 特性。

【问题讨论】:

    标签: python performance iterator sublist


    【解决方案1】:

    itertools.islice:

    from itertools import islice
    
    itr = (i for i in range(10))
    m, n = 3, 8
    result = list(islice(itr, m, n))
    print(result)
    # [3, 4, 5, 6, 7]
    

    此外,如果需要,您可以添加一个参数作为step

    itr = (i for i in range(10))
    m, n, step = 3, 8, 2
    result = list(islice(itr, m, n, step))
    print(result)
    # [3, 5, 7]
    

    【讨论】:

    • 是的:对于 m=5000n=6000,即相对较小的数字,这种方法确实比我的快 40%。不幸的是,我将不得不重组我最初的问题,因为没有办法处理甚至是 1e15 元素的块——但这是一个不同的问题。
    • @MrArsGravis 您面临的具体问题是什么?我的回答能解决你的问题吗?
    • 是的,您发布了一个解决方案,而且比我建议的更快。我想我会保持这个问题,以防其他人有不同的建议,但事实似乎并非如此。至于我最初试图解决的问题:迭代序列的大块需要太长时间,所以我采取了不同的方式来解决它,但我认为这个问题仍然有其自身的优点......
    • 我明白了。这是有道理的,但在我看来,你不能比这更快。如果有什么东西可以击败专门为此目的设计的标准库函数,我会感到惊讶。
    猜你喜欢
    • 2022-11-27
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    相关资源
    最近更新 更多