【问题标题】:How to optimize checking thousands of list elements thousands of times? [duplicate]如何优化检查数千个列表元素数千次? [复制]
【发布时间】:2021-10-22 10:18:55
【问题描述】:

我正在尝试开发一个程序,通过“Collat​​z 猜想函数”运行前 n 个整数,表示为“c(x)”,其中任何奇数都更新为自身的三次加 1,任何偶数被更新为自身的一半,并一直运行直到数字更新为 1。这只是作为一个编程练习。我不想用这个来证明什么。我只是想了解一些优化,比如位操作。

为了加快这个过程,我让它创建了一个它通过这个函数生成的每个唯一数字的列表,如果它生成了一个先前生成的数字,那么它会移动到下一个输入。然而,这会产生一个问题,即每次再次运行该函数时都会花费 loads 时间检查列表中的每个元素(称为“nums”)。

我使用的代码如下所示:

if x not in nums:
    nums.append(int(x))
    c(x)

有没有办法更快地检查这个列表中已经生成的数字?或者是否有一种完全不同的方式可以消除对列表的需求和/或完全检查每个元素?一旦你开始超过 n = 100,000(意味着 100,000 个起始输入),检查列表需要明显更长的时间,并且任何优化都可以减少整个小时的计算更大的 n 值。

【问题讨论】:

  • 如果您不关心元素的顺序,请将 nums 设置为集合而不是列表。检查集合成员资格比列表快得多。
  • 明确地说,您所说的“检查”只是 x not in nums 部分? IE。您只想快速检测是否x in nums
  • 顺便说一句,假设c 是此代码所在的函数,您可能不想将递归用于可能是简单的while 循环的东西。 Python默认不实现尾递归优化,你写的甚至可能不是正确的尾递归(如果你不知道这一切意味着什么:记住,当你调用一个函数时,它最终将不得不@ 987654325@ 某处;当您从自身内部调用当前函数时,不是“转到”函数顶部。)
  • @JohnGordon 我实际上完全忘记了 set 是这样做的,我还没有和他们合作太多,所以这真的很有帮助。
  • @KarlKnechtel 是的,我基本上只是在寻找一种更快的方法来检测列表中的值(或任何最有效的迭代方法,如本例中的集合),或者完全找到更快的解决方案。这是减慢我的程序速度的主要原因,同时消耗了大量内存,尾递归只是我的首选方法,所以我几乎只是希望它能够工作,一个 while 循环而不是一个完整的循环我从来没有想过递归函数。

标签: python list optimization collatz


【解决方案1】:

如果您将算法实现为递归函数,那么我建议查看functools 函数cache(或lru_cache)。

如果您有一个处理密集型函数,这些装饰器将存储给定输入的结果,因此,如果稍后在同一进程中再次调用该函数,则该函数可以返回先前计算的结果。对于高度递归的算法(例如阶乘,在一定程度上还有 collat​​z),这可以节省大量时间。

也就是说,如果您以递归方式实现该算法,则可能会达到 Python 的递归限制。

【讨论】:

  • 很高兴您对此做出回应,cache 使整个程序更加优化,不仅在速度方面,而且我还设法将我的代码压缩成 9 行,所以这正是我的需要!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
  • 2014-08-08
  • 1970-01-01
  • 1970-01-01
  • 2018-10-29
  • 2014-12-27
相关资源
最近更新 更多