我有一个大的可迭代项,实际上,由以下给定:
itertools.permutations(range(10))
我想访问百万分之一的元素。我确实以不同的方式解决了问题。
强制迭代到列表并获取第1000000个元素:
return list(permutations(range(10)))[999999]
手动跳过直到999999的元素:
p = permutations(range(10))
for i in xrange(999999): p.next() return p.next()
手动跳过元素v2:
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元素:
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()函数返回到默认值。
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倍。