1
  • Python 编程中是否有用于确定安全测试值的方法?确保意外的大值不会导致风险的东西。
  • 我读过 Python 不鼓励类型检查。在这种情况下应该进行类型检查或边界检查还是有其他选择?


我正在使用此代码并测试运行时间。我不小心输入了一个非常大的数字并运行了代码。当它达到 850MB RAM 使用率并上升时,我能够通过任务管理器停止它。我不希望类似的事情再次发生。

def primes_list(num):
    ans = [2]
    for i in range(3, num, 2):

        temp = False
        for j in ans:
            if i % j == 0 or j*j > i:
                temp = True
                break

        if temp == False:
            ans.append(i)
    else:
        return ans
4

4 回答 4

1

如果 num 是一个非常大的数字,您最好使用xrange而不是range。所以改变这一行

for i in range(3, num, 2):

for i in xrange(3, num, 2):

这将为您节省大量内存,因为该范围会在内存中预先分配列表。当 num 很大时,列表会占用大量内存。

如果你想限制内存使用,只需在执行任何操作之前检查 num 即可。

于 2013-05-24T11:41:37.407 回答
1

在 linux bash 上,有一个功能ulimit可以限制任何正在运行的进程的内存。将此添加到您的程序中,并将print num其作为 primes_list 函数的第一行

try:
    primes_list(10)
    primes_list(100)
    primes_list(1000)
    primes_list(10000)
    primes_list(100000)
    primes_list(1000000)
    primes_list(10000000)
    primes_list(100000000)
except MemoryError:
    print "out of memory"

然后您应该能够看到以下功能在 shell 中工作。请注意,我启动了一个新的 bash shell。结束 shell 将使 ulimit 设置恢复正​​常。当然可以编写脚本。在此示例中,我将虚拟内存大小限制为 100MB

$ bash
$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 63064
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 63064
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
$ ulimit -v 100000
$ python foo.py 
10
100
1000
10000
100000
1000000
10000000
out of memory
于 2013-05-24T11:59:13.100 回答
1

您的确切问题是您在命令行测试函数时输入了太大的值。这里的解决方案不是以任何方式修改函数,而是使用自动化测试。

最简单的自动化测试只是意味着编写另一个函数来调用你的函数并确保它返回正确的值。计算机完全按照您在命令行中所做的工作。但是,自动化方法更好,因为您的测试函数保存在一个文件中 - 您不需要每次都在命令提示符下键入您的测试值。所以你基本上不会输入错误的数字和内存溢出。还有很多 其他 优点

Python 的标准库包含模块unittest旨在帮助您组织和运行单元测试。unittest 这里有更多的例子。替代方案包括Nosepy.test,它们都与unittest.


primes_list您的功能示例:

import unittest

class TestPrimes(unittest.TestCase):
    def test_primes_list(self):
        pl = primes_list(11)  # call the function being tested
        wanted = [2,3,5,7,11]  # the result we expect
        self.AssertEqual(pl, wanted)

if __name__ == "__main__":
    unittest.main()

为了证明自动化测试有效,我编写了一个测试,它会因为你的函数中的错误而失败。(提示:当提供的最大值是素数时,它不会包含在输出中)

于 2013-05-24T12:16:13.417 回答
0

你不是想列出素数吗?不知道这是否会帮助你,但仍然:

def primes(n): // n is the maximum number we want to check
    if n==2: return [2] // 2 is the lowest prime number
    elif n<2: return [] // there's no prime number below 2
    s=range(3,n+1,2) // range from 2 by 2 numbers, leave out even numbers
    mroot = n ** 0.5 // get's the root of maximum number
    half=(n+1)/2-1
    i=0
    m=3
    while m <= mroot: // no point in checking above the root of the highest number
            if s[i]:
                    j=(m*m-3)/2
                    s[j]=0
                    while j<half:
                            s[j]=0
                            j+=m
            i=i+1
            m=2*i+3
    return [2]+[x for x in s if x] // final array consists of 2 and the rest of primes

有关素数确定算法的更多信息,请查看:

http://en.wikipedia.org/wiki/Primality_test

找到素数最快的算法是什么?

于 2013-05-24T11:38:22.770 回答