当前位置: 首页 > 面试题库 >

以迭代方式跳过元素的优雅方式

华睿识
2023-03-14
问题内容

我有一个大的可迭代项,实际上,由以下给定:

itertools.permutations(range(10))

我想访问百万分之一的元素。我确实以不同的方式解决了问题。

  1. 强制迭代到列表并获取第1000000个元素:

    return list(permutations(range(10)))[999999]
    
  2. 手动跳过直到999999的元素:

    p = permutations(range(10))
    

    for i in xrange(999999): p.next()
    return p.next()

  3. 手动跳过元素v2:

    p = permutations(range(10))
    

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

  4. 使用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倍。



 类似资料:
  • 问题内容: 我有这个AngularJS应用。一切正常。 现在,当满足特定条件时,我需要显示不同的弹出窗口,我想知道什么是最好的处理方式。 目前,我正在评估两个选项,但是我绝对会接受其他选项。 选项1 我可以为弹出窗口创建新的HTML元素,然后直接从控制器附加到DOM。 这将打破MVC设计模式。我对这种解决方案不满意。 选项2 我总是可以在静态HTML文件中插入所有弹出窗口的代码。然后,使用,我可以

  • 我有这个角度JS应用程序。一切都很好。 现在,我需要在特定条件成立时显示不同的弹出窗口,我想知道最好的方法是什么。 目前我正在评估两个选项,但我绝对愿意接受其他选项。 我可以为弹出窗口创建新的超文本标记语言元素,并直接从控制器附加到DOM。 这将打破 MVC 设计模式。我对这个解决方案不满意。 我总是可以在静态超文本标记语言文件中插入所有弹出窗口的代码。然后,使用,我可以只隐藏/显示正确的弹出窗口

  • 问题内容: 输入: 输出: 什么是最优雅的(阅读:Pythonic)书写方式? 问题答案: 我自己会写一个生成器,但是像这样:

  • 问题内容: 在Python 2.7中执行元组算术的最优雅,简洁的方法(不创建带有运算符重载的我自己的类)? 可以说我有两个元组: 我的预期结果是 我目前使用: 我也尝试过: 但结果是。我相信以上内容是嵌套的for循环,导致4次迭代和4个值。 问题答案: 如果您正在快速寻找,可以使用numpy: 如果您想将其保存在一个元组中:

  • 我怎样才能以更聪明的方式做到这一点?是否有一些库可以使用反射或类似的方法返回给定JavaBean的元素集合?

  • 假设我有一个服务方法,我在其中执行一些验证/REST调用等(例如,中的someServiceMethod2),并希望以事务方式使其安全。我还有一个repoMethod,它包含一个事务。当父事务引发异常时,如何回滚子事务? 有没有办法在一个事务中加入这两种方法?就像< code>TransactionDefinition。PROPAGATION _ REQUIRED PROPAGATION将在Spr