2011-10-13 107 views
3

Python Problem Set这三个函数可以正常工作,但它们需要每次执行一个函数才能移到下一个函数以获得最终结果。有没有办法从全部三个中获得结果,而无需单独查询每个结果?合并功能以减少查询

>>> import itertools 

>>> def prime_factors(value): 
    if value > 3: 
     for this in itertools.chain(iter([2]), xrange(3,int(value ** 0.5)+1, 2)): 
      if this*this > value: break 
      while not (value % this): 
       if value == this: break 
       value /= this 
       yield this 
    yield value 

>>> prime_factors(315) 
generator object prime_factors at 0x01182468> 

>>> def prime_factors_mult(n): 
    res = list(prime_factors(n)) 
    return sorted([fact, res.count(fact)] for fact in set(res)) 

>>> prime_factors_mult(315) 
[[3, 2], [5, 1], [7, 1]] 

>>> def totient(n): 
    from operator import mul 
    if n == 1: return 1 
    return reduce(mul, [(p-1) * p**(m-1) for p,m in prime_factors_mult(n)]) 

>>> totient(315) 
144 
+0

不完全确定您的意思是“从三个中获取结果而不必逐个查询每个结果”。你的意思是按顺序打三个电话吗?如果是这样,你可以创建一个函数来调用它们中的三个,并返回一个数组(例如)和结果。我有没有错过这一点? – pcalcao

+0

等等,这是欧拉总数(phi)函数吗? – Blender

+0

我会做的第一件事是缓存素数列表,如果需要更大的素数则扩展它。这会显着加快对'prime_factors'的调用,并且如果只需要''totient'值,可能会加快速度。 – 9000

回答

1

您可以将第二个2,但发电机应保持发电机:

In [1]: import itertools 
In [2]: from operator import mul 

In [3]: def prime_factors(value): 
      if value > 3: 
       for this in itertools.chain(iter([2]), xrange(3,int(value ** 0.5) + 1, 2)): 
        if (this * this) > value: 
         break 
        while not (value % this): 
         if value == this: 
          break 
         value /= this 
         yield this 
      yield value 

In [4]: def totient(n): 
      if n != 1: 
       res = list(prime_factors(n)) 
       prime_factors_mult = sorted([fact, res.count(fact)] for fact in set(res)) 
       retValue = reduce(mul, [(p-1) * p**(m-1) for p,m in prime_factors_mult]), prime_factors_mult 
      else: 
       retValue = n 
      return retValue 

In [5]: x = totient(315) 

In [6]: print x 
(144, [[3, 2], [5, 1], [7, 1]]) 

In [7]: print x[0] 
144 

In [8]: print x[1] 
[[3, 2], [5, 1], [7, 1]] 

实际上,你可以将所有3,并有1个函数返回的3元组是什么每个返回值将是:

import itertools 
from operator import mul 

def totient(n): 
    if n == 1: return 1 
    res = list() 
    value = int("%d" % n) 
    if value > 3: 
     for this in itertools.chain(iter([2]), xrange(3,int(value ** 0.5)+1, 2)): 
      if this*this > value: break 
      while not (value % this): 
       if value == this: break 
       value /= this 
       res.append(this) 
    res.append(value) 
    prime_factors_mult = sorted([fact, res.count(fact)] for fact in set(res)) 
    return res, reduce(mul, [(p - 1) * p**(m - 1) for p,m in prime_factors_mult]), prime_factors_mult 

x = totient(315) 

# This would be the returned list from prime_factors(315) 
print x[0] 
[3, 3, 5, 7] 

# This would be the returned value from totient(315) 
print x[1] 
144 

# This would be the returned list from prime_factors_mult(315) 
print x[2] 
[[3, 2], [5, 1], [7, 1]] 

# The 3-tuple: 
print x 
([3, 3, 5, 7], 144, [[3, 2], [5, 1], [7, 1]]) 
+0

质量因素是否仍然可以从总体函数中原始的'prime_factors_mult'返回? – Astron

+0

@Astron检查我的编辑,我把它变成了一个单一的函数,它返回每个函数本身会返回的三元组('[3,3,5,7],144,[[3,2],[ 5,1],[7,1]])'。 – chown

+0

感谢您的快速回答! – Astron