在Python里打印一个由字符“x”构成的对角线矩阵,本质是利用二维下标规律控制输出内容。所谓对角线“x”字符,通常是指一个N行N列的方阵,只有在主对角线(行索引等于列索引)和副对角线(行索引加列索引等于N减一)的位置打印x,其余位置打印空格。掌握这个规律后,我们可以用最基础的嵌套循环实现,也可以借助列表推导式写出更简洁的版本。

一、基础嵌套循环实现
最直观的方式是使用两层for循环,外层控制行,内层控制列。在每一行中,我们判断当前列索引是否满足对角线条件,如果满足就打印x,否则打印空格。由于print函数默认换行,需要通过设置end参数为空字符串来阻止自动换行,并在每行结束后手动换行。
下面的示例定义了一个函数,接收边长n作为参数,打印对应的对角线x矩阵。注意Python中range是从0开始到n减一,因此主对角线条件为i == j,副对角线条件为i + j == n - 1。两个条件用逻辑或连接即可。
def print_diagonal_x(n):
for i in range(n):
for j in range(n):
if i == j or i + j == n - 1:
print('x', end='')
else:
print(' ', end='')
print()
# 打印边长为5的矩阵
print_diagonal_x(5)
运行上述代码,控制台会输出如下图形:
x x
x x
x
x x
x x
</p>
<p>这种写法的优点是逻辑清晰、易于理解,非常适合初学者体会行列下标与图形之间的映射关系。缺点是频繁调用print会带来一定的性能开销,且在输出较大矩阵时效率偏低,但在练习和小型矩阵场景下完全够用。</p>
<h2>二、使用列表推导式优化</h2>
<p>如果我们希望代码更紧凑,可以利用字符串的join方法配合列表推导式,在内存中先拼好每一行的字符串,再统一打印。这样每行只调用一次print,代码可读性也不错。</p>
<p>核心思想仍然是下标判断,只不过把内层循环改写成对range(n)的推导,根据条件选择'x'或' ',然后用空串把它们连起来。示例如下:</p>
<pre class=brush:python;toolbar:false>
def diagonal_x_lines(n):
lines = []
for i in range(n):
row = ''.join('x' if i == j or i + j == n - 1 else ' ' for j in range(n))
lines.append(row)
return lines
for line in diagonal_x_lines(6):
print(line)
以上代码输出边长为6的矩阵,两个对角线交叉于中心,图形左右对称。将构造逻辑和打印逻辑分开,也方便后续把结果写入文件或做单元测试。
列表推导式版本比纯print嵌套循环少了很多函数调用,在n较大时差异更明显。同时由于返回的是字符串列表,调用方可以灵活决定如何展示,比如用换行符join后一次性输出,而不必在构造函数内部耦合打印行为。
三、常见误区与边界处理
很多人在写这类题时会误把副对角线条件写成i + j == n,导致最后一行和第一列错位。正确关系来自:副对角线上行号与列号之和恒等于n减一,因为索引从0开始。另一个容易忽略的点是当n为偶数时,两条对角线没有重合格子;当n为奇数时,中心格子同时满足两个条件,但我们的或判断不会重复打印,只是同一个位置输出一次x,因此无需特殊处理。
如果希望矩阵看起来更“方形”而不是因字符宽度显得扁,可以考虑用等宽字体环境运行,或者把空格换成点号之类的占位符辅助观察。此外,若从用户处接收n,应做正整数校验,避免传入0或负数导致range出错或打印空内容。
def safe_diagonal_x(n):
if not isinstance(n, int) or n <= 0:
raise ValueError('n必须是正整数')
for i in range(n):
print(''.join('x' if i == j or i + j == n - 1 else '.' for j in range(n)))
safe_diagonal_x(4)
上面的safe_diagonal_x用点号代替空格,能更清楚地看到非对角线区域,同时也演示了基本的输入校验。实际项目中,把校验、构造、输出各司其职,代码会更健壮也更易维护。
四、扩展到其他字符与组合图形
对角线打印的本质是坐标判定,因此把x换成任意字符都只是条件分支里的字符串常量变化。你还可以组合多条线,比如同时打印主对角线、副对角线和边框,只需在判断条件中增加j == 0或j == n - 1等边界情况。
理解了这个模式,类似打印空心菱形、叉形、棋盘格等练习都能举一反三。建议初学时先在纸上标出行列索引,找到数学关系再写代码,能大幅减少调试时间。
def cross_and_border(n):
for i in range(n):
row = ''
for j in range(n):
if i == j or i + j == n - 1 or j == 0 or j == n - 1:
row += '#'
else:
row += ' '
print(row)
cross_and_border(5)
该示例在对角线基础上加了左右边框,输出像一个带叉的方框。由此可见,只要理清楚“哪几个坐标该输出特殊字符”,剩下的只是拼接与打印的细节。Python的字符串与循环工具足以优雅地覆盖这类控制台图形任务。