【问题标题】:My Nested For loops Run "faster" than inline For loop我的嵌套 For 循环比内联 For 循环运行“更快”
【发布时间】:2021-10-25 02:40:52
【问题描述】:

对于我所在的一个类,我们被要求编写一个蛮力方法,用于在列表 S1S2 中查找 2 个元素,它们添加到指定的值x。到目前为止,我已经把它写出来了:

@timing
def brute_force_nested(x, s1 : list, s2 : list) -> bool:
    for a in s2:
        for b in s1:
            if a + b == x:
                return True
    return False

@timing
def brute_force_inline(x, s1 : list, s2 : list) -> bool:
    return bool([ (a,b) for a in s2 for b in s1 if a + b == x ])

但是当我在终端中运行它们时,我得到的时间差异非常大:

>>> brute_force_nested(5123, S1, S2):

func:brute_force_nested took: 0.007085800170898438 sec and gave: True

>>>func:brute_force_inline(5123, S1, S2)

func:brute_force took: 3.0208868980407715 sec and gave: True

为什么会这样?我的印象是内联语法本质上只是写出嵌套循环的语法糖,但显然有些不同,我不知道是什么。

【问题讨论】:

  • 您的嵌套 for 循环在找到第一个匹配项后立即停止,这要归功于返回;列表推导用所有匹配拳头创建一个列表,然后给它布尔函数

标签: python loops time


【解决方案1】:

循环确实是相等的,但不是打破它的条件。在第一个嵌套循环中,代码在达到第一个相等时停止。在第二个中,计算所有测试,直到用尽所有组合。

第一个循环与理解语法的等价物是使用生成器和any,当达到第一个真值时,它将停止

return any((a+b==x for a in s2 for b in s1))

【讨论】:

  • @Jab 谢谢!在我的手机上打字,不容易有一个很好的概览;)
【解决方案2】:

这是因为您只在第一个函数中迭代列表并返回第一个值。第二个您正在创建一个列表,然后评估该列表的真实值。为了使它们具有可比性,您需要使用 any 和生成器理解。

def brute_force_inline(x, s1 : list, s2 : list) -> bool:
    return any(a + b == x for a in s2 for b in s1)

P.S 从技术上讲,您的两种方法都是嵌套循环,一种只是使用理解完成。

这也可以使用itertools.product 更有效地完成:

from itertools import product

def brute_force_inline(x, s1 : list, s2 : list) -> bool:
    return any(sum(ab) == x for ab in product(s2, s1))

【讨论】:

  • 您认为product 的速度如何?
  • 因为嵌套的 for 循环是在 C 和原生 python 中运行的。在这种情况下,效率差异可以忽略不计。
  • for a, b in 在 Python 中运行同样多。但总是必须分配 两个 值而不是一个,这使得它的效率较低。你能在更有效的地方展示输入吗?
  • 考虑我的编辑。
猜你喜欢
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 2019-06-27
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多