我有一个很大的可迭代,实际上是一个大的迭代,由下式给出:
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以其他方式访问迭代的具体元素,或者至少以更优雅的方式跳过第一个元素,或者如果我只需要使用一个以上.
使用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倍.