2012-03-13 3 views
3

해결책은 아마도 간단하지만, 나는 그 사실을 알 수 없습니다. 코드는 간단합니다. 피보나치 숫자 생성기입니다. 목표는 4,000,000 이하의 모든 피보나치 수를 합산하는 것입니다.파이썬 : 모듈러스 연산자로 이상한 행동이 있습니다.

내 접근 방식은 첫째 4,000,000 아래의 모든 피보나치 숫자를 생성하는 것입니다, 다음 중 하나를 은)로부터 이상한 것들을 제거 (이 잘 작동) b)는 "심지어") 짝수 사람과 (새로운 목록을 생성 목록 "모두"

그러나 후자의 경우 출력은 이해할 수없는 이유 때문에 다음과 같습니다. [2, 5, 8, 21, 34, 89, 144, 377, 610, 1597 , 2584, 6765, 10946, 28657, 46368, 121393, 196418, 514229, 832040, 2178309, 3524578]

어떤 도움을 많이 주셨습니다. 감사!

all = [] 
even = [] 

def fibonacci(): 
    a, b = 1, 2 
    while a < 4000000: 
     all.append(a) 
     a, b = b, a + b 
    print all 

##Putting all the even fibonacci numbers in a different list and summing them up works fine 
# for i in all: 
#  if i % 2 == 0: 
#   even.append(i) 
# print even     
# print sum(even) 


# But for some strange reason I can't figure out how to remove the odd numbers from the list 
    for i in all: 
     if i % 2 != 0: 
      all.remove(i) 

    print all 
    print sum(all) 

fibonacci() 
+0

을 당신이 변수 이름으로 "모두"사용하지 않는 것이 좋습니다 :

당신은 단순히 슬라이스 연산자를 사용하여 그렇게 할 수 있습니다. [all] (http://docs.python.org/library/functions.html#all)이라는 매우 유용한 내장 함수가있어서 편리합니다. – DSM

+0

DSM, 이것을 지적 해 주셔서 감사합니다! – talkinghead

+0

또한 누군가가 fibonacci 시퀀스에 대해 궁금해하는 경우 : 예, 일반적으로 0, 1, 1, 2, ...로 시작하지만이 문제에 대한 Project Euler 지침에서는 1, 2, ...로 시작합니다. – talkinghead

답변

4

목록에서 항목을 제거하면서 목록을 반복하는 동안 목록을 변경하면 목록이 변경되어 반복이 예상치 않게 발생합니다. 이 시도 :

... 
# But for some strange reason I can't figure out how to remove the odd numbers from the list 
    for i in all[:]: 
     if i % 2 != 0: 
      all.remove(i) 
... 

이 "조각"표기라고 무엇이며, 당신의 반복이 all.remove에 의해 영향을받지 않도록 목록의 일회용 사본을 반복하는 당신의 원인()를 호출합니다.

+3

대체 용액 간결하고 논증 할 수있을 정도로 명확하고 적어도 (전체 목록을 복사 할 때와 같이) 새로운 목록을 만들기 위해 필터링하는 것입니다 :'all = [x에 대한 x는 모두 x % 2 == 0]'입니다. – delnan

+0

네, 목록의 이해력이 좋아 보이는군요. 직접 코드를 작성하면 아마 그렇게 될 것입니다. 나는 당신이 대답으로 그것을 썼다면 나는 투표 할 것입니다! 그러나 나는 보통 내 대답이 질문자에게 더 유용하다는 것을 알게된다. 그래서 나의 SO 스타일은 문제에 대해 최소한의 차이를 만들어 올바르게 행동하게 만든다. – mattbornski

+0

매트, 설명 주셔서 대단히 감사합니다. 또한 필자는 Delnan의 솔루션보다 훨씬 쉽게 이해할 수있는 원래 코드에 대한 수정을 발견합니다. Python 개발자로서 Delnan의 코드가 더 명확 할 수도 있지만, 나에게 너무 간결합니다. 나는 메모를 만들었습니다. 몇 달 안에, 나는 그것을 또한 좋아할지도 모른다. .. – talkinghead

-1

인덱스 i의 항목을 숫자 "i"가 삭제하기 때문입니다.

+3

나는 그것이 사실이라고 생각하지 않는다. '파이썬 2.7.2 (기본, 2011 년 11 월 14 일, 19시 37 분 59 초) 다윈에있는 [GCC 4.2.1 (도트 3)] (GCC 4.2.1) "help", "copyright", "credits "또는"라이센스 "를 참조하십시오. 이상이다 >>> foo는 = [5, 4, 3, 2, 1] >>> foo.remove (5) >>> foo를 [4, 3, 2, 1] ' – mattbornski

3

반복 할 목록에서 항목을 제거 할 수 없습니다. 파이썬은리스트의 시작을 기준으로 현재 인덱스만을 알고있는 반복자를 사용합니다. 목록 앞에서 항목을 제거하면 모든 요소의 위치가 변경되고 다음 요소는 건너 뜁니다.

당신은 발전기 예를 들어, 많은 방법으로 문제를 방지 할 수 있습니다

: 반복 다음 코드에서 발생하는 방법을

def fibonacci(): 
    a, b = 1, 2 
    while a < 4000000: 
     yield a 
     a, b = b, a + b 

def even(seq): 
    for item in seq: 
     if item % 2 == 0: 
      yield item 

print sum(even(fibonacci())) 
0

우리가 면밀히 관찰하면

for i in all: 
     if i % 2 != 0: 
      all.remove(i) 

      # Add these two lines for debugging.. 
      # Or to know how this iteration functions 

      print "when %d: " %i 
      print all 

    print "Remaining Evens", 
    print all 

이 어떻게 출력이 것입니다 최대 숫자가 100 인 것처럼 보입니다.

original series [1, 2, 3, 5, 8, 13, 21, 34, 55, 89] 
when 1: 
[2, 3, 5, 8, 13, 21, 34, 55, 89] 
when 3: 
[2, 5, 8, 13, 21, 34, 55, 89] 
when 13: 
[2, 5, 8, 21, 34, 55, 89] 
when 55: 
[2, 5, 8, 21, 34, 89] 
Remaining Evens [2, 5, 8, 21, 34, 89] 

여기 파이썬이 시작될 때 목록 반복, 기술적으로, 우리는 첫 번째 반복에서 출력

을 관찰하면, 그것은 1.

제거

그것이 반복한다있는 숫자의 위치를 ​​.. 기억 다음 반복에서는 2 위를 셉니다. 이제 목록은 "2"에서 시작됩니다. 따라서 두 번째 위치는 "3"입니다. 따라서 그것을 제거합니다.

다음 반복에서 세 번째 위치에서 계산해야한다는 것을 기억합니다. 이제 현재 목록에서 세 번째 위치는 "8"입니다. 그래서, 그것은 "5"에서 온 것이 아닙니다. 따라서 8이 만족하지 못하면 13에 이릅니다.

따라서이 숫자는 건너 뜁니다.

어떻게이 문제를 해결하려면 :

사실, 당신은 "모든"목록 및 반복 처리의 복사본을 만들 필요가있다. (동일한 객체를 참조하면 안됩니다.). 만약 그렇다면, 똑같은 일이 일어난다.

copy_all= all[:] 

#or else, you need to use deepcopy() 

import copy 
copy_all = copy.deepcopy(all) 

# you iterate copy_all but delete in all. 

However, prefer the first method. Its very simple. 
관련 문제