在Python中打印简单的菱形图案

5
我想在 Python 3.5 中打印以下这个图案(我是编程新手):
    *
   ***
  *****
 *******
*********
 *******
  *****
   ***
    *

但是我只知道如何使用以下代码打印下面的内容,但不确定如何将其反转以使其成为完整的菱形:
n = 5

print("Pattern 1")

for a1 in range (0,n):
    for a2 in range (a1):
        print("*", end="")
    print()

for a1 in range (n,0,-1):
    for a2 in range (a1):
        print("*", end="")
    print()

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

非常感谢你的帮助!


考虑到每一行你要打印的都是由空格和星号组成的(例如,第一行是4个空格,1个星号,第二行是3个空格,3个星号等等)。你所需要做的就是找出每一行应该有多少个空格和星号。 - Pavel Gurkov
我该如何打印空格? - Ali R.
2
打印星号的方法和这个一模一样。 - Pavel Gurkov
没关系!我使用了("")而不是(" ")!我现在会尝试并更新您,如果它成功了! - Ali R.
18个回答

11

因为最中间和最大的星号行有9个星号,所以你应该将n设为9。你已经成功打印出了钻石图案的一半,但现在你需要尝试编写一个函数,按照特定数量的空格和星号进行打印。因此,请尝试开发每行空格和星号数量的模式。

Row1: 4 spaces, 1 star, 4 spaces
Row2: 3 spaces, 3 stars, 3 spaces
Row3: 2 spaces, 5 stars, 2 spaces
Row4: 1 space, 7 stars, 1 space
Row5: 0 spaces, 9 stars, 0 spaces
Row6: 1 space, 7 stars, 1 space
Row7: 2 spaces, 5 stars, 2 spaces
Row8: 3 spaces, 3 stars, 3 spaces
Row9: 4 spaces, 1 star, 4 spaces

那你能推断出什么呢?从第一行到第 (n+1)/2 行,随着星号数量的增加,空格数量减少。所以在 1 到 5 行时,# of stars = (row number * 2) - 1,而 # of spaces before stars = 5 - row number

现在从第(n+1)/2 + 1行到第9行,空格数量增加而星号数量减少。所以在 6 到 n 行时,# of stars = ((n+1 - row number) * 2) - 1,而 # of spaces before stars = row number - 5。

通过这些信息,你应该能够编写出类似以下的程序:

n = 9
print("Pattern 1")
for a1 in range(1, (n+1)//2 + 1): #from row 1 to 5
    for a2 in range((n+1)//2 - a1):
        print(" ", end = "")
    for a3 in range((a1*2)-1):
        print("*", end = "")
    print()

for a1 in range((n+1)//2 + 1, n + 1): #from row 6 to 9
    for a2 in range(a1 - (n+1)//2):
        print(" ", end = "")
    for a3 in range((n+1 - a1)*2 - 1):
        print("*", end = "")
    print()

请注意,您可以将n替换为任何奇数来创建具有该行数的完美菱形。


另一种看待它的方式是这样(下面),但它类似于半个菱形,其中n是从第1行到最大星号,而不是总行数。这样可以消除使用偶数时的奇怪形状。我看了你解释的方法,并尝试提出另一种方法,而不是进行除法,并遵循类似于半个菱形的策略。for b1 in range(n): for b2 in range(n-b1): print(" ", end="") for b3 in range((b1*2)-1): print("*", end="") print() - Ali R.
当然,你可以再次使用for b1 in range(n,0,-1) - Ali R.

8
这里提供一种基于高度等于到中间部分的解决方案,即高度的一半。例如,在下面输入高度为4(7)或5(9)。这种方法将产生奇数实际高度。
h = int(input("please enter diamond's height:"))

for i in range(h):
    print(" "*(h-i), "*"*(i*2+1))
for i in range(h-2, -1, -1):
    print(" "*(h-i), "*"*(i*2+1))

# please enter diamond's height:4
#      *
#     ***
#    *****
#   *******
#    *****
#     ***
#      *
#
# 3, 2, 1, 0, 1, 2, 3  space
# 1, 3, 5, 7, 5, 3, 1  star

# please enter diamond's height:5
#       *
#      ***
#     *****
#    *******
#   *********
#    *******
#     *****
#      ***
#       *
#
# 4, 3, 2, 1, 0, 1, 2, 3, 4  space
# 1, 3, 5, 7, 9, 7, 5, 3, 1  star

这里是另一种以高度等于从上到下的方式来解决问题的方案,或者说是实际总高度。例如,下面输入高度为7或9。当用户输入偶数高度时,菱形将会稍微倾斜。

h = int(input("please enter diamond's height:"))

for i in range(1, h, 2):
    print(" "*(h//2-i//2), "*"*i)
for i in range(h, 0, -2):
    print(" "*(h//2-i//2), "*"*i)

# please enter diamond's height:7
#      *
#     ***
#    *****
#   *******
#    *****
#     ***
#      *
#
# 3, 2, 1, 0, 1, 2, 3  space
# 1, 3, 5, 7, 5, 3, 1  star
#
# please enter diamond's height:9
#       *
#      ***
#     *****
#    *******
#   *********
#    *******
#     *****
#      ***
#       *
#
# 4, 3, 2, 1, 0, 1, 2, 3, 4  space
# 1, 3, 5, 7, 9, 7, 5, 3, 1  star

4
无需使用 eval,应使用 int - sanyassh
@sanyassh 因为 eval 存在安全风险,根据你的建议,我改编了代码。 - Karl Knechtel

6
我今天学到了一个非常简单的解决方案,想要分享一下。 :)
num = 9

for i in range(1, num+1):
  i = i - (num//2 +1)
  if i < 0:
    i = -i
  print(" " * i + "*" * (num - i*2) + " "*i)

逻辑如下:
(这里将一个空格表示为“0”)
# i = 1 | new i = 1 - 5 = -4 | * : 9 - 8 = 1 | 0000 + * + 0000
# i = 2 | new i = 2 - 5 = -3 | * : 9 - 6 = 3 | 000 + *** + 000
# i = 3 | new i = 3 - 5 = -2 | * : 9 - 4 = 5 | 00 + ***** + 00
# i = 4 | new i = 4 - 5 = -1 | * : 9 - 2 = 7 | 0 + ******* + 0
# i = 5 | new i = 5 - 5 = 0  | * : 9 - 0 = 9 |    ********* 
# i = 6 | new i = 6 - 5 = 1  | * : 9 - 2 = 7 | 0 + ******* + 0
# i = 7 | new i = 7 - 5 = 2  | * : 9 - 4 = 5 | 00 + ***** + 00
# i = 8 | new i = 8 - 5 = 3  | * : 9 - 6 = 3 | 000 + *** + 000
# i = 9 | new i = 9 - 5 = 4  | * : 9 - 8 = 1 | 0000 + * + 0000

结果将会是以下内容:
    *    
   ***   
  *****  
 ******* 
*********
 ******* 
  *****  
   ***   
    *    

5
正如马丁·埃文斯在他的帖子中指出的那样:https://stackoverflow.com/a/32613884/4779556,解决菱形模式的可能方法是:
side = int(input("Please input side length of diamond: "))

for x in list(range(side)) + list(reversed(range(side-1))):
    print('{: <{w1}}{:*<{w2}}'.format('', '', w1=side-x-1, w2=x*2+1))

正如我所说,我是Python的新手,我还没有学习过那种方法,只知道一些命令。 - Ali R.
1
@Ali R - 这是一个初学者的解决方案,比上面那个更容易。打印语句中的花括号看起来很复杂,但一旦你学会了它们,就会发现它们其实很简单。 - Shaken_not_stirred.

1
另一种可能性。根据使用的是哪个(空格或星号),将其转换为绝对值(我使用了空格)。此实现不需要将菱形分成两个循环(上半部分和下半部分)。
def diamond(n):
    star = 1
    main = ''
    # if required to manage zero or negative n
    if n%2 == 0:
        return None
    if n<0:
        return None
    else:
        for i in range(1,n+1):
            string = ''
            space = abs(i - int((n+1)/2))
            star = n - 2 * space
            string = space * ' ' + star * '*' + '\n'
            main += string
        # not necessary but useful to visualize diamond 
        #print(main)
        return(main)

1

这有两个版本

  1. 星号之间有空格
  2. 星号之间没有空格

星号之间有空格

n = 4
for i in range(n):
    print(' '*(n-i-1) + '* '*(i+1) )
for i in range(n):
    print(' '*(i+1) + '* '*(n-i-1))

enter image description here

没有星号之间的空格
n = 4
for i in range(n):
    print(' '*(n-i-1) + '*'*((2*i)+1) )
for i in range(n):
    print(' '*(i+1) + '*'*((2*((n-1)-i))-1))

enter image description here


1
最简单的答案
n=5
for i in range(1,n+1):
    print ((n-i)*(" ")+(i*" *"))

for i in range(n-1,0,-1):
    print((n-i)*(" ")+(i*" *"))

希望这能帮助到某些人。

0
side = int(input("side length: "))
count = 0
bl = 0
while count < side:
    x = side - count
    print (x * " ", (count * "*") * 2)
    count += 2
while count >= 0:
    print (bl * " ", (count * "*") * 2)
    count -= 1
    bl += 1

如果您想让上下两部分相同,请将 "count += 2" 更改为 "count += 1"。

0
#author Tahir Baku
#have fun
print "\nWelcome to diamond builder"
print "\n----D.I.A.M.O.N.D  B.U.I.L.D----"
diagonal=int(input("Give me the diagonal: "))
s=1
h1=1
h=(diagonal-1)/2
diagonal1=diagonal-2
while s<=diagonal:
     print (' '*h+'*'*s+' '*h)
     h=h-1
     s=s+2
while diagonal1>=0:
     print (' '*h1+'*'*diagonal1+' '*h1)
     h1=h1+1
     diagonal1=diagonal1-2

虽然这段代码可能回答了问题,但是提供关于为什么和/或如何回答问题的额外上下文可以提高其长期价值。 - Alex Riabov

0

简单的方法...

n= 11 #input is even number 1,3,5,...
a = 1
b = 1
for a in range(n+1):
    if a%2 != 0:
        val = (n - a) // 2
        print (" "*val + "*"*(a) + " "*val ,end = "\n")
for b in range(n-1,0,-1):
    if b%2 != 0:
        val2 = (n-b)//2
        print (" "*val2 + "*"*(b) + " "*val2 ,end = "\n")

输出:

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

或者使用反转方法,第一个是钻石形,第二个是一系列的钻石形

import copy
n = 10       #input: size of diamon
raw  = []
lst = []
re_lst = []

for a in range(n+1):
    if a%2 != 0:
        val = (n - a) // 2
        raw = ''.join(" "*val + "*"*(a) + " "*val)
        lst.append(raw)
        re_lst = copy.deepcopy(lst)
lst.reverse()
#print diamond
for i in re_lst:
    print(i)
for i in lst:
    print(i)
print("\n")
#print series of diamond
for i in re_lst:
    print(i)
    for i in lst:
        print(i)

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