2011-10-13 142 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