这主要练习for循环语句,练习目标是输出指定行数的星号菱形,如:
为了能介绍清楚,我们可以从最简单的开始。比如先简化思路,输出三角形:
甚至可以再简单些,以输出星号矩形:
最后最简单的方式就是先输出一行星号:
这个一行星号虽然简单,但是仅仅凭借目前学习的内容还真不能完成,如:
cols = 5
for i in range(cols):
print('*')
输出为:
正常的print函数会在输出完内容后自动换行。因此,可以通过在print函数中设置end参数为空字符(默认该参数为换行),来取消这个默认的自动换行即可:
cols = 5
for i in range(cols):
print('*', end='')
输出为:*****
这里的cols变量可以控制输出的星号个数,后期可以由用户输入来确定,以实现动态指定个数的效果。有同学可能会问,为什么不这样写:
print('*****')
这样写虽然效果有,但是这样代码就写死了,不具有运行动态设置星号个数的特点。不过,可以使用一种Python的特殊用法:
cols = 5
print('*' * cols)
输出内容同上。这个星号运算符(位于'*'字符串和cols变量中间)表示将星号前面字符串的内容重复星号后面变量指定的次数。
好,再次回到星号矩阵练习。这需要两个循环嵌套,一个控制行数,一个控制每行的个数(即列数):
rows = 3
cols = 5
for i in range(rows):
for j in range(cols):
print('*', end='')
运行界面如:
为什么显示为一行了呢?仔细观察代码,会发现根本没有任何换行的输出,print默认的输出完自动换行的功能也已经通过end参数设置而取消。
事实上,我们这里并不是不需要换行,而是在每一行结束后,还是需要一个换行!即每一行输出完若干列星号后,输出一个换行:
rows = 3
cols = 5
for i in range(rows):
for j in range(cols):
print('*', end='')
print()
输出为:
最后一行print函数,虽然没有任何输出,但是默认会至少输出一个自动换行,达到目的。但是请注意缩进的层次,它是位于每一行的循环语句中,和每一列循环属于并列关系,也就是说,输出完每一列后,才输出一个换行。
为了实现三角形的效果:
我们不妨还是简化下,先控制输出为:
对于这个输出,行数并不变,只是每一行的星号列数有变化,而且每行还不一样,因此问题的关键就在于改变内循环的次数:
这个cols现在具有什么特点呢?仔细观察即可发现这个规律:
因此修改代码为:
rows = 3
for i in range(rows):
for j in range(i * 2 + 1):
print('*', end='')
print()
输出为:
如果希望实现这个输出:
就需要思考这个居中对齐是如何实现的?一种简单的思路就是通过输出空格,也就是说,第一行的星号前其实有两个空格,第二行星号前有一个空格,以此类推。所以需要在输出每一行的星号前,增加多个空格的输出,而且这个空格的个数也是逐行变化:
这个空格数量的变化规律为:
因此修改代码为:
rows = 3
for i in range(rows):
for j in range(rows - i - 1):
print(' ', end='')
for j in range(i * 2 + 1):
print('*', end='')
print()
运行界面为:
有的电脑运行可能会显得这些星号不是很居中,略微左倾或者右倾,这个原因在于字体,有些系统使用的是不等宽字体,这样就会导致不对齐,这个问题需要设置等宽字体才能解决。设置方法为,在PyCharm中,选择File——Settings——Editor——Font,设置font为等宽字体即可:
有了这些基础知识以后,我们就可以完成最后的练习。菱形可以看成是两个三角形:
可以考虑通过输出两个三角形完成这个练习,这个大家可以尝试下。
但是我们这里还考虑一种新的方法,一个大循环完成整个菱形的绘制。问题的关键就在于要控制好每行输出空格和星号的个数,先统计下:
这里的空格个数呈现出由大到小再到大的变化特点,星号正好相反。如果把行号(第几行)看成是x,那么空格个数可以看成是y,两者呈现出一种相关变化关系。如何表达计出这个数值变化效果呢?这就需要数学函数!不同的数学函数有不同的变化特点,我们来看一种:
这是指数曲线,显然此时的y和x不具有由大到小再到大的特点。我们再看一个:
这是绝对值函数,仔细观察它具有x值在从原点左边向右边变化时,y值呈现由大到小再到大的变化特点!
按照这个规律,空格个数可以分析为:
星号个数可以分析为:
最终可以形成完整代码:
rows = 5
for i in range(rows * 2 - 1):
for j in range(abs(rows - i - 1)):
print(' ', end='')
for j in range((rows - abs(rows - i - 1)) * 2 - 1):
print('*', end='')
print() # 换行
当然,也可以使用刚才所介绍的字符串重复操作符来实现相同功能:
rows = 5
for i in range(rows * 2 - 1):
print(' ' * abs(rows - i - 1), end='')
print('*' * ((rows - abs(rows - i - 1)) * 2 - 1), end='')
print() # 换行
更进一步,可以将rows变量设置让用户输入来指定,实现动态输出指定行数的效果:
rows = int(input())
for i in range(rows * 2 - 1):
for j in range(abs(rows - i - 1)):
print(' ', end='')
for j in range((rows - abs(rows - i - 1)) * 2 - 1):
print('*', end='')
print() # 换行