안티 패턴은 이미 상태 변수와 재귀를 사용하고
를 발견했습니다.이 페이지의 다른 답변은 같은 실수
def avg (tree):
def helper (node, sum, count):
if node is None:
return (0, 0)
else:
(Lsum, Lcount) = helper(node.left, 0, 0)
(Rsum, Rcount) = helper(node.right, 0, 0)
return (node.data + Lsum + Rsum, 1 + Lcount + Rcount)
(sum, count) = helper(tree, 0, 0)
return sum/count if count > 0 else None
# your node class
class Node (object):
def __init__(self, data, left, right):
self.data = data
self.left = left
self.right = right
# make your tree
tree = Node(5, Node(3, Node(2, None, None), None), Node(6, None, None))
print(avg(tree)) #=> 4.0
# ensure that this works for an empty tree too (it does)
print(avg(None)) #=> None
을하여 실패한
직관
재귀는 우리가 이것에 대해 정말 좋은 직관 개발할 수 있습니다 - 특히 가 굵은 라인
을
(Lsum, Lcount) = helper(node.left, 0, 0)
(Rsum, Rcount) = helper(node.right, 0, 0)
return (node.data + Lsum + Rsum, 1 + Lcount + Rcount)
그 return
은 retu 좌우 합계가 카운트위한
이다 불문 합,이 노드의 데이터 플러스 (sum, count)
- 터플을 RN은, (1)을 더한대로 좌우을이 노드 카운트 카운트가 이런 식으로 작성하여
을, 우리는 매우 명확하게 우리의 기능을 처리하는 두 경우를 볼 수 있습니다
노드
None
경우 1,515,
- , 우리는 그렇지 않으면, 우리는 노드
data
카운트 의 합 및 1
기여 최종 계산
(0, 0)
에 기여.
인라인 코드를 설명
# we only need to expose one function
def avg (tree):
# helper isn't exposed outside of avg
# helper has stateful parameters
def helper (node, sum, count):
# helper is a recursive function, start with the base case of empty Node
if node is None:
# our base sum and count are 0
return (0, 0)
# process the Node
else:
# get L sum and count the same way we initialized helper with the tree
(Lsum, Lcount) = helper(node.left, 0, 0)
# do the same for the R side
(Rsum, Rcount) = helper(node.right, 0, 0)
# no reassignment of sum or count is necessary,
# simply recurse using the new state values of each
return (
node.data + Lsum + Rsum, # sum equals this node plus L and R sums
1 + Lcount + Rcount # count equals 1 plus L and R counts
)
# always init the sum and count with 0
(sum, count) = helper(tree, 0, 0)
# don't divide by zero if the tree is empty; instead return None
return sum/count if count > 0 else None
모든 중간 값 정리
은의이
,369 살펴 보자(Lsum, Lcount) = helper(node.left, 0, 0)
(Rsum, Rcount) = helper(node.right, 0, 0)
return (node.data + Lsum + Rsum, 1 + Lcount + Rcount)
나 같은 사람이라면 재 할당을 사용하여 다른 답변을 크게 개선 했음에도 불구하고 여전히 중간 값이 사용되고 있습니다. 우리가 이것을 약간 정리할 수 있다면 좋을 것입니다.
튜플 목록을 취할 수있는 함수가 있고 해당 위치에 모든 값을 추가하면 어떨까요?
// if only ...
sum_tuples((0, 10), (1, 20), (2, 30))
# ... (0 + 1 + 2 , 10 + 20 + 30)
#=> (3, 60)
그 기능이 zip
의 도움으로 작성하기 위해 실제로 매우 쉽게 밝혀졌습니다.이 기능은 우리의 avg
기능 이외의 장소에서 유용하므로 작업이 일반적이다, 그래서 나는 이제 별도
def sum_tuples (*xs):
return tuple(sum(x) for x in zip(*xs))
sum_tuples((0,10), (1,20), (2,30))
#=> (3, 60)
그것을 정의가 avg
에 미치는 영향을 살펴 보겠습니다 - 에서 더 이상 중간 값 (변경 굵은)는 이전과 동일하게 작동 물론 def avg (tree):
def helper (node, sum, count):
if node is None:
return (0, 0)
else:
return sum_tuples( (node.data, 1),
helper(node.left, 0, 0),
helper(node.right, 0, 0)
)
(sum, count) = helper(tree, 0, 0)
return sum/count if count > 0 else None
만 지금은 할 수있는 막으로 아름답다.
'_'은 무엇을 의미합니까? –
무슨 뜻인지 알겠지만 위의 구문을 설명해 주시겠습니까? –
@VeeshaDawg 답변을 확장했습니다. –