파이썬 3. 파이썬 2 result[p] == 0
에 result[p] < 10
한다면, 당신은 메인 루프를 통해 때마다 무슨 일을하는지 것은 : 이중 각 숫자가, 그 다음 자리에 여분의 수만을 가지고 다니십시오. 문제는 가장 높은 자릿수의 경우 다음 자릿수가 존재하지 않는다는 것입니다.
그래서 여기에 해결책이 있습니다. 2 이외의 다른 전원에서는 작동하지 않지만 해결책은 아래에 나와 있습니다.
def foo():
result={0:2}
for i in range(2,10):
for p in result.keys():
result[p]*=2
for p in result.keys()[:]:
if result[p]/10 != 0:
result[p+1] = result.get(p+1, 0) + result[p]/10
result[p] = result[p] % 10
원래 코드와 두 가지 주요 변경 사항이 있습니다.
첫 번째로 result.keys()
의 끝에 [:]
을 추가하여 현재 키가 아닌 루프 앞에 사전의 키 집합을 반복합니다. 그 이유는 마지막 숫자가 5보다 크면 사전에 새 키를 추가 할 것이므로 반복하는 동안 키를 사용하지 않아도된다는 것입니다. (왜? 몇 가지 이유가 있지만 사전은 임의적 인 순서이며, 키를 추가 할 때마다 전체 주문이 변경 될 수 있습니다. 나중에도 중요합니다.)
두 번째로 원래 질문 : r_p
을 저장할 것인지 또는 기존 값에 r_p
을 추가 할 것인지를 결정하기 위해 if p+1 in result
을 확인하지 않아도됩니까?
카운트를 처리 할 때 collection.Counter
을 사용합니다. 이는 dict
과 같으며 정수 만 저장하며 누락 된 키의 값은 0입니다.그렇지 않은 경우 일반적으로 collection.defaultdict
을 사용합니다. 누락 된 모든 키가 갖는 기본값을 지정할 수 있다는 점을 제외하면 dict
과 같습니다. Counter
또는 defaultdict
을 사용하면 필요한 것은 result[p+1] += result[p]/10
입니다.
그러나 나는 다른 대안을 사용했습니다 : 에 get
메서드를 사용 했으므로 기본값을 지정할 수 있습니다. 이유는 나중에 설명 하겠지만 일반적으로 get
에 도달하면 defaultdict
또는 Counter
을 대신 입력해야합니다.
그래서, 지금은 실행, 작업, 2의 거듭 제곱을위한 그러나 그것은 두 가지 이유로, 다른 힘에 대해 작동하지 않습니다 수 있습니다 :
첫째, 우리는이 임의의 순서로 수행하고 있습니다. 2의 거듭 제곱의 경우, 가장 많이 휴대 할 수있는 것은 1이며, 1이 다음 자리가 올라갈 지 여부에 영향을 미칠 수있는 방법은 없습니다. (8은 나르지 않으며 8 + 1도 없을 것이며, 이제는 9를 얻는 방법이 있습니다.) 그러나 다른 어떤 힘을 위해서, 그것은 사실이 아닙니다.
dict
으로 시작하여 적은 수의 작은 키 (실제로는 작은 키를 추가 할 경우) (CPython 2.7 및 3.2 이상)가 발생하므로 간단한 테스트에서이를 알지 못합니다. 해시 값은 있지만 작은 정수는 자신을 해시 된 순서대로 정렬하고 아무 것도 삭제하지 않으면 dict
은 순서대로 반복 (인쇄)됩니다. 그러나 일반적으로 주문은 예측할 수 없으며 사용자가 신뢰할 수 없습니다.
이 문제의 해결책은 키가 추가 된 순서대로 반복하는 collections.OrderedDict
을 사용하는 것입니다. 그래서 defaultdict
또는 Counter
을 사용하지 않으려는 것입니다. OrderedDict
으로 전환해야하는 경우 유일한 옵션은 get
입니다.
두 번째로, 지수가 10을 초과하면 100을 수행해야 할 수도 있습니다. 즉, 10을 지니고 있다는 의미이므로 다음 자릿수가 0이더라도 그 자리가 계속 이어집니다. 즉, 미리 키를 복사하십시오. 예를 들어, 우리가 75의 힘을 발휘한다고 가정 해 보겠습니다. {0:5, 1:7}
으로 시작하십시오. 각 자릿수를 75로 곱하면 {0:375, 1:525}
가됩니다. 이제 37 : {0:5, 1:562}
을 휴대하십시오. 이제 56 : {0:5, 1:2, 2:56}
을 휴대하십시오. [0, 1]
은 원래 키의 복사본을 반복하기 때문에 5를 수행 할 기회가 없습니다.
이 문제를 해결하기 위해 최선을 다합니다.
그러나 기존의 장소를 수정하는 대신 새 사전을 만드는 것이 좋습니다. 그런 다음 이러한 모든 문제를 해결할 수 있습니다. (일반적으로 상태를 변경하는 대신 순수한 함수를 사용하면 많은 문제가 발생하지만 추가 복사 비용이 발생합니다.)
def double(d):
result = Counter()
for p in d:
result[p] += d[p] % 10
result[p+1] += d[p]/10
return result
digits={0:2}
for i in range(2,10):
for p in digits:
digits[p]*=2
digits = double(digits)
게시 된 코드는 'result [p] 'result [p + 1] '이 아닙니다. – Amber
빠른 질문 : 왜 [2, 1, 5]리스트 대신에'{0 : 2, 1 : 1, 2 : 5}'를 사용하고 있습니까? 어느 쪽이든,'x [0] == 2','x [1] == 1','x [2] == 5'. – abarnert
@Amber : 죄송합니다. 내 목표는 {0:16}을 {0 : 6, 1 : 1}로 설정했기 때문에 둘 다 변경해야한다는 것을 이해합니다. – acs