我怎样才能重写这个Python操作,这样它就不会挂起我的系统?

时间:2015-04-23 22:22:34

标签: python

初学者,寻找答案,但找不到答案。

我知道(或者更确切地说是怀疑)以下代码的部分问题是组合列表的大小。

(也许,最后一行看起来像是一个错误,因为,如果我只是运行'打印...而不是'梳子+ = ......'它会快速运行并退出。是否会更加优雅?)

我不能100%确定系统挂起是由于磁盘I / O(交换?),CPU使用还是内存...在Windows下运行它似乎会导致相当大的磁盘I /系统' O,而在Linux下,top在它被杀之前显示出高CPU和内存使用率。但在这两种情况下,系统的其余部分在此操作进行时都无法使用(直接在Python解释器中以及在PyCharm中尝试过它。)

所以有两个问题:1)是否存在一些“安全”问题。测试这样不会对系统其他部分造成负面影响的代码的方法,以及2)对于这个具体的例子,我应该如何重写它?

尝试此代码(我不推荐!):

from itertools import combinations_with_replacement as cwr
comb = []
iterable = [1,2,3,4]
for x in xrange(4,100):
  comb += cwr(iterable, x)

谢谢!

编辑:应该已经指定了,但这里也是python2.7代码(猜测xrange很明显它反正不是3)。挂起的Windows机器有4 GB的RAM,但看起来挂起在磁盘I / O上。我曾经(并且仍在)工作的原始问题是在codewars.com上的一个问题,关于有多少种方法可以根据可能的硬币列表进行更改。我提出的解决方案是少量工作,而不是大工作。显然,我需要提出一个更好的算法来解决这个问题...所以这肯定是非必要的代码。但是,我想知道我是否可以设置编程环境,以便我的代码中的错误不会以这种方式传播和阻塞我的系统。

进一步编辑: 我今晚再次处理这个问题,并意识到我并不需要附加到主列表(正如你们中的一些人在评论中向我暗示的那样),而只是处理收集的子集。我没有给出足够的代码来证明这一点,但我的关键问题是这一行:

梳子+ = cwr(可迭代,x)

应该是

comb = cwr(iterable,x)

2 个答案:

答案 0 :(得分:5)

由于您尝试使用替换计算组合,因此必须考虑的排序数量 4 ^ nth power 。(4因为您的iterable有4个项目)。

更一般地说,要计算的排序数量是可以在列表中任何位置的元素数量,增加到列表的长度。

你正在尝试计算3到99之间n的4 ^ n次幂.4 ^ 99次幂 4.01734511064748 * 10 59

我担心即使量子计算机也无法帮助计算它。

答案 1 :(得分:1)

这不是一台功能非常强大的笔记本电脑(3.7 GiB,英特尔®赛扬®CPUN2820 @ 2.13GHz×2,64位ubuntu),但它在15秒左右就完成了(但确实显着减慢,顶部显示为100%) cpu(双核)和35%内存。如果完成则需要大约15秒来释放内存。

len(梳子)是4,421,240

我必须将您的代码更改为

from itertools import combinations_with_replacement as cwr
comb = []
iterable = [1,2,3,4]
for x in xrange(4,100):
  comb.extend(list(cwr(iterable, x)))

ED - 按照您的原件重新尝试,它运行正常。我的错。它看起来好像是内存要求。如果你真的需要这样做,你可以将它写入文件。

re-ED对上面的封套后复杂度计算感到好奇而不是平衡我的经验,我尝试将n(X轴)与combination_with_replacement()(Y轴)返回的列表长度一起绘制为可迭代长度2,3,4,5 i。结果似乎低于n **(i-1)(这与我上面的4,99得到的数字有关。实际上是(i + n-1)!/ n!/(i-1)!近似于n **(i-1)/ i!比n大得多

log log plot of list size v. n for different lengths of iterable

另外,运行绘图我没有在内存中保留完整的梳子列表,这确实提高了计算机性能,所以也许这是一个相关的点:而不是生成一个巨大的列表然后在它之后工作,做循环中的计算。