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

잠깐, 이것이 오일러 totient (phi) 함수입니까? – Blender

+0

내가 할 수있는 첫 번째 일은 큰 소수가 필요할 경우 확장하여 소수의 목록을 캐싱하는 것입니다. 'prime_factors'에 대한 호출 속도가 상당히 빨라지므로 _one_' 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 개의 튜플을 리턴하는 1 개의 단일 함수로 만들었습니다. ([3, 3, 5, 7], 144, [[3,2], [ 5, 1], [7,1])). – chown

+0

빠른 답변 주셔서 감사합니다! – Astron