如何在Python3中打印/输出重叠的菱形

4
如何输出n个重叠的菱形,每个菱形的高度为2n-1。以下是n = 3的输出要求:
  *   *   *
 * * * * * *
* * * * * * *
 * * * * * *
  *   *   *

n = 4

   *     *     *     *
  * *   * *   * *   * *
 * * * * * * * * * * * *
* * * * * * * * * * * * *
 * * * * * * * * * * * *
  * *   * *   * *   * *
   *     *     *     *

n = 5

    *       *       *       *       *
   * *     * *     * *     * *     * *
  * * *   * * *   * * *   * * *   * * *
 * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * *
  * * *   * * *   * * *   * * *   * * *
   * *     * *     * *     * *     * *
    *       *       *       *       *

我尝试使用循环编写代码,成功输出了与输入n相对应的每个形状。然而,我无法将钻石形状显示在“单行”上,只能像这样显示在多行中:

n = 3

  *
 * *
* * *
 * *
  *
  *
 * *
* * *
 * *
  *
  *
 * *
* * *
 * *
  *

这是我使用的代码:

n = int(input()) #for number of diamonds per row
height = 2*n - 1

for j in range(1, n + 1): #for printing h no. of diamonds
    #from row 1 to middle row
    for row in range(1, (height + 1)//2 + 1):
        for spaces in range((height + 1)//2 - row): #print spaces per row
            print(" ", end = "")
        for stars in range((2*row) - 1): #print stars per row
            if stars % 2 == 0:
                print("*", end = "")
            else:
                print(" ", end = "")
        print()

    #from middle row to last row
    for row in range((height + 1)//2 + 1, height + 1):
        for spaces in range(row - (height + 1)//2):
            print(" ", end = "")
        for stars in range((height + 1 - row)*2 - 1):
            if stars % 2 == 0:
                print("*", end = "")
            else:
                print(" ", end = "")
        print()

1
你的外层循环应该是针对菱形行数的。 - quamrana
4个回答

2
这是一种打印菱形的方法。
每个循环都会创建一行空格列表,并在其中放置部分 n 个菱形,然后一次性打印该行:
n = int(input()) #for number of diamonds per row

for row in range(n):
    expanse = [' ']*(n+1)*(n-1)*2
    spaces_before = n-row-1
    stars = '* '*(row+1)
    for diamond in range(n):
        prefix = spaces_before + diamond*(n-1)*2
        expanse[prefix : prefix+len(stars)-1] = stars
    print(''.join(expanse))

for row in range(n-1):
    expanse = [' ']*(n+1)*(n-1)*2
    spaces_before = row+1
    stars = '* '*(n-row-1)
    for diamond in range(n):
        prefix = spaces_before + diamond*(n-1)*2
        expanse[prefix : prefix+len(stars)-1] = stars
    print(''.join(expanse))

输出结果与问题所述相符。

更新:将内部循环替换为列表切片。


2
这个怎么样?
n = 4

for i in list(range(1, n+1)) + list(range(n-1, 0, -1)):
    rowpattern = (' '*(n-i) + '* '*(i) + ' '*(n-i)) * n
    print(rowpattern)

编辑:根据下面的评论,这更加准确:

n = 4

for i in list(range(1, n)) + list(range(n, 0, -1)):
    rowpattern = ' ' * (n-i) + ('* ' * (i if i!=n else i-1) +
        ' ' * (2 * (n - i) - 2)) * n + '*' *(1 if i==n else 0)
    print(rowpattern)

输出略有不同 - Lucas Wieloch

0
def print_diamonds(n):

    from functools import lru_cache

    number_of_peaks = n
    step_size = (n * 2) - 2

    @lru_cache(maxsize=n)
    def get_star_indecies(y):
        star_index_offset = 2 * y
        begin = star_index_offset
        end = (number_of_peaks * step_size) + begin

        star_indecies = {*range(begin, end, step_size)}
        if y == 0:
            return star_indecies
        else:
            return star_indecies | get_star_indecies(y-1)

    for iteration in range(n*2-1):
        y = -abs(iteration-(n-1))+(n-1)
        star_indecies = get_star_indecies(y)
        line_length = max(star_indecies) + 1
        space_offset = n-y-1
        space_padding = " " * space_offset
        line = space_padding
        for index in range(line_length):
            line += [" ", "*"][index in star_indecies]
        print(line)


def main():

    print_diamonds(5)

    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())

0
这是我对所提出问题的答案:
class Diamond(object):
    def __init__(self, size=3):
        self.size = size
        self.max_line_size = (size*2) + 1
        self.max_line = [self.one_line(size)]
        self.lines_below = map(self.one_line, range(size-1, 0, -1))
        self.lines_above = self.lines_below[::-1]
        self.lines = self.lines_above + self.max_line + self.lines_below

    def __str__(self):
        return "\n".join(self.lines)

    def one_line(self, num_of_diamonds):
        line_size = (num_of_diamonds * 2) + 1
        line = list()
        for i in range(1, line_size+1):
            el = "*" if (i % 2 == 0) else " "
            line.append(el)
        str_line = "".join(line)
        return  (" " * ((self.max_line_size - line_size)/2)) + str_line + (" " * ((self.max_line_size - line_size)/2))

class Diamonds(object):
    def __init__(self, size=3):
        self.size = size
        self.diamond = Diamond(size)

    def __str__(self):
        return "\n".join([i[:-1] + (i[2:-1]*(self.size-1)) for i in self.diamond.lines])

print(Diamonds(3))
print(Diamonds(4))
print(Diamonds(5))

我采用了与你完全不同的方法,但主要区别在于 Diamonds 类中的 __str__ 方法。我的方法将钻石打印在一行中,因为我正在生成一个包含所有已生成并连接到换行符之前调用 print 的大字符串。在你的情况下,似乎每次完成每个钻石的每一行的生成时都会调用 print,而 print 的默认行为是在打印其输入后换行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接