有什么方法可以改进此python代码以计算帕斯卡三角形中的偶数吗?

时间:2018-08-16 11:12:36

标签: python

这是我编写的一段代码,用于计算帕斯卡三角形的前1023行中有多少个偶数。但是,我觉得可能需要改进,尤其是功能next_row。

def next_row(r):
    i = 0
    s = []
    while i < len(r) -1:
        s.append(r[i] + r[i+1])
        i += 1
    s.insert(0, 1)
    s.append(1)
    return s

def count_even(r):
    counter = 0
    for item in r:
        if item % 2 == 0:
            counter += 1
    return counter

def results(i, t, e):
    print('In the first ' + str(i) + ' lines of the pascal triangle, there are ' + str(t) + ' entries. ' + 
        str(e) + ' of them are even.')

r = [1]
even = 0
total = 0
for i in range (0, 1023):
    even += count_even(r)
    total += len(r)
    r = next_row(r)
    results(i+1, total, even)

4 个答案:

答案 0 :(得分:1)

恕我直言,您的代码还可以,我建议只使用

let diagram = document.getElementById('diagram')
let diagramImg = document.getElementById('diagram-image')
let startX;
let startY;
let walkX;
let walkY;
let dragging = false;

diagram.addEventListener('mousedown', (e) => {
  dragging = true;
  startX = e.pageX - diagram.offsetLeft;
  startY = e.pageY - diagram.offsetTop;
})

diagram.addEventListener('mousemove', (e) => {
  if (!dragging) return;
  e.preventDefault();
  let x = e.pageX - diagram.offsetLeft;
  let y = e.pageY - diagram.offsetTop;

  walkX = x - startX
  walkY = y - startY
  console.log(walkX, walkY)

  diagramImg.style.top = walkY + 'px'
  diagramImg.style.left = walkX + 'px'
})

diagram.addEventListener('mouseleave', () => {
  dragging = false;
})

diagram.addEventListener('mouseup', () => {
  dragging = false;
})

代替

for i in range(len(r) -1):
    s.append(r[i] + r[i+1])

PS 如果您改用

while i < len(r) -1:
    s.append(r[i] + r[i+1])
    i += 1

您将看到结果没有改变,正如@John Coleman所建议的那样,它起作用了。但是,如果将Pascal三角形打印出来,它会退化为0和1的集合。

在这种情况下,您可以简化count_even:

for i in range(len(r) -1):
    s.append(r[i] ^ r[i+1])

答案 1 :(得分:0)

使用列表推导,只需使您的代码(前两个功能)的详细程度略低。这样,您无需初始化i=0和一个空列表s=[],而无需初始化while循环来跟踪i。在您的count_even函数中,您还可以使用以下counter = len(r[r%2==0]) 提供的 r是一个数组(在您的代码中是一个列表)。

def next_row(r):
    s = [r[i] + r[i+1] for i in range(len(r)-1)]
    s.insert(0, 1)
    s.append(1)
    return s

def count_even(r):
    counter =  len([i for i in r if i%2 == 0])
#   counter = len(r[r%2==0]) #  If 'r' is an array
    return counter

我保持不变。

答案 2 :(得分:0)

为使代码更具可读性和紧凑性,我建议您使用以下解决方案,其中包含评论 f字符串理解(而不是经典的for循环)。主要思想是存储每行的内容,每行中元素的总数以及3个列表中每行中偶数元素的数量。这样,如果以后需要,您可以将Pascal三角形的所有值保留在列表中:

# Initialize first line
lines  = [[1]]  # list of contents of each line (lists)
evens  = [0]    # list of counts of even elements in each line (integers)
totals = [1]    # list of total counts of elements in each line (integers)

# Build next lines
for i in range(1023):
    print(f'In the first {i+1} lines of the pascal triangle, there are {sum(totals)} entries. {sum(evens)} of them are even.')
    lines.append([1] + [lines[i][j] + lines[i][j+1] for j in range(len(lines[i])-1)] + [1])
    totals.append(len(lines[-1]))
    evens.append(len([v for v in lines[-1] if v%2 == 0]))

答案 3 :(得分:0)

对于初学者,在读取数组的内容时,应该避免while循环和索引上的迭代。观看loop like a native谈话以获取更多见解。在您的情况下,由于您有兴趣一次遍历连续的值,因此可以查看pairwise recipe

第二,您可以提供更大的行来开始计算,而不是在所有中心元素的计算之后在 之后打补丁,方法是在两边都加0。为了避免改变列表的大小,可以使用itertools.chain

最后,要获得1023个第一行,您可能想要提供一个生成器,该生成器从pascal三角形中给出无穷的行流,并使用itertools.islice在1023行之后将该生成器切短。

修改后的代码:

import itertools


def pairwise(iterable):
    a, b = itertools.tee(iterable)
    next(b, None)
    return zip(a, b)


def next_row(row):
    larger_row = itertools.chain([0], row, [0])
    return [a + b for a, b in pairwise(larger_row)]


def pascal_triangle():
    row = [1]
    while True:
        yield row
        row = next_row(row)


def count_even(iterable):
    return sum(item % 2 == 0 for item in iterable)


def main(limit):
    even = total = 0
    for index, row in enumerate(itertools.islice(pascal_triangle(), limit), 1):
        even += count_even(row)
        total += len(row)
        print('In the first', index, 'lines of the pascal triangle, '
              'there are', total, 'entries.', even, 'of them are even.')


if __name__ == '__main__':
    main(limit=1023)