当前位置:  开发笔记 > 编程语言 > 正文

优雅的方式来跳过迭代中的元素

如何解决《优雅的方式来跳过迭代中的元素》经验,为你挑选了1个好方法。

我有一个很大的可迭代,实际上是一个大的迭代,由下式给出:

itertools.permutations(range(10))

我想访问第一百万个元素.我已经以某种不同的方式解决了问题.

    将iterable转换为list并获取1000000th元素:

    return list(permutations(range(10)))[999999]
    

    手动滑动元素直到999999:

    p = permutations(range(10))
    for i in xrange(999999): p.next()
    return p.next()
    

    手动滑动元素v2:

    p = permutations(range(10))
    for i, element in enumerate(p):
        if i == 999999:
            return element
    

    使用itertools中的islice:

    return islice(permutations(range(10)), 999999, 1000000).next()
    

但我仍然觉得这些都不是python的优雅方式.第一个选项太昂贵,它需要计算整个迭代只是为了访问单个元素.如果我没有错,那么islice在内部执行的方法与我在方法2中所做的相同,并且几乎完全是第3次,也许它有更多的冗余操作.

所以,我只是好奇,想知道是否有python以其他方式访问迭代的具体元素,或者至少以更优雅的方式跳过第一个元素,或者如果我只需要使用一个以上.



1> Martijn Piet..:

使用itertools配方consume跳过n元素:

def consume(iterator, n):
    "Advance the iterator n-steps ahead. If n is none, consume entirely."
    # Use functions that consume iterators at C speed.
    if n is None:
        # feed the entire iterator into a zero-length deque
        collections.deque(iterator, maxlen=0)
    else:
        # advance to the empty slice starting at position n
        next(islice(iterator, n, n), None)

注意islice()那里的电话; 它使用n, n,实际上没有返回任何东西,并且该next()函数回退到默认值.

简化为您想要跳过999999个元素的示例,然后返回元素1000000:

return next(islice(permutations(range(10)), 999999, 1000000))

islice() 处理C中的迭代器,这是Python循环无法击败的东西.

为了说明,以下是每种方法仅重复10次的时间:

>>> from itertools import islice, permutations
>>> from timeit import timeit
>>> def list_index():
...     return list(permutations(range(10)))[999999]
... 
>>> def for_loop():
...     p = permutations(range(10))
...     for i in xrange(999999): p.next()
...     return p.next()
... 
>>> def enumerate_loop():
...     p = permutations(range(10))
...     for i, element in enumerate(p):
...         if i == 999999:
...             return element
... 
>>> def islice_next():
...     return next(islice(permutations(range(10)), 999999, 1000000))
... 
>>> timeit('f()', 'from __main__ import list_index as f', number=10)
5.550895929336548
>>> timeit('f()', 'from __main__ import for_loop as f', number=10)
1.6166789531707764
>>> timeit('f()', 'from __main__ import enumerate_loop as f', number=10)
1.2498459815979004
>>> timeit('f()', 'from __main__ import islice_next as f', number=10)
0.18969106674194336

islice()方法比下一个最快的方法快近7倍.

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有