使用Map-Reduce时Python中的延迟布尔评估

时间:2014-05-31 18:30:35

标签: python lazy-evaluation reduce

我将使用我的例子:我想使用Eratosthenes的筛子创建一个素数列表。 对于每个数字,我检查它是否是复合数,如果没有,我将它附加到列表中。

  • 使用"标准"编程:

    primes = [2]
    start = time.time()
    for i in xrange(3,primeRange,2):
        isPrime = True
        for p in primes:
            if(i % p == 0):
                isPrime = False
                break;
        if(isPrime):        
            primes.append(i)
    print "Using C++-style: ", time.time() - start, " seconds"
    
  • 使用reduce功能:

    start = time.time()
    for i in xrange(3,primeRange,2):
        if(reduce(lambda x,y:x and y,[i % p != 0 for p in primes])):
            primes.append(i)
    print "Using map-reduce: ", time.time() - start, " seconds"
    

primeRange = 100000的结果:

Using map-reduce:  54.1150000095  seconds
Using C++-style:  4.62000012398  seconds

第二种情况使代码更紧凑,但将对整个列表评估条件,然后缩减为True / False。有没有办法避免这种情况?

3 个答案:

答案 0 :(得分:3)

您可以将all与生成器表达式一起使用:

if all(i % p != 0 for p in primes)

生成器表达式将一次懒惰地评估一个术语,如果all遇到不满足条件的值,{{1}}将提前返回。

答案 1 :(得分:2)

是的,你应该做两件事。

首先,如果您想避免完全评估列表理解,请不要使用列表推导,请使用生成器表达式:

... [i % p != 0 for p in primes] ...

应该是

... (i % p != 0 for p in primes) ...

第二,reduce()并不了解lambda x,y:x and y可能会失败,而且没有办法教它。但这并不重要,因为python有一个内置函数,可以精确地折叠连接幺半群,all(),所以if应该是

if all(i % p != 0 for p in primes):

答案 2 :(得分:0)

使用生成器,

for (int i = 0; i < iX; i++) {
  int value = X[i];
  int index1 = idClause
  int index2 = iEP[idClause]
  explicitsPropagations[index1][index2] = value;
}