【问题标题】:issue with else part printing pattern其他部分打印图案的问题
【发布时间】:2021-12-31 15:40:46
【问题描述】:

我正在尝试打印以下模式。但无法实现倒字模式 任何建议或简洁的方法

预期输出:

                   01 
                02 01 
             03 02 01 
          04 03 02 01 
       05 04 03 02 01 
          04 03 02 01
             03 02 01
                02 01
                   01

代码:

n=10
var=''
breaking = int((n+1)/2)
dec = 2
space=2
cnt=1
for row in range(1,n+1):
  if row <= breaking:
    print(' ' * ( (n - 1) * 3 ) + str(row).zfill(2) + ' ' + var )
    var = str(row).zfill(2) + ' ' + var 
    n = n-1
  else:
    print(' ' *  ((n*2) + (breaking + space) + cnt) + var[dec:])
    space = space + 2
    dec = dec + 2
    cnt = cnt + 1

上面的代码在下面打印出异常的图案如何解决?

                   01 
                02 01 
             03 02 01 
          04 03 02 01 
       05 04 03 02 01 
           04 03 02 01 
             4 03 02 01 
                03 02 01 
                    02 01 
                      2 01 

【问题讨论】:

  • 下半部分的空格数必须减少。例如。您可以(而不是“if”)创建两个 for 循环,一个用于上半部分,然后另一个用于下半部分,其中行数减少(“range”的“step”参数)。这让事情变得容易多了。
  • print(' ' * ((n*2) + (breaking + space) + cnt) + var[dec:]) 用你自己的话来说,这部分代码的目的是什么?您是否尝试检查它为((n*2) + (breaking + space) + cnt) + var[dec:]) 计算的值?你能用手算出应该是什么值吗?你得到正确的结果了吗?
  • 请阅读ericlippert.com/2014/03/05/how-to-debug-small-programs 并尝试一次跟踪您的代码逻辑。

标签: python


【解决方案1】:

问题是您在 else 块中循环的每次迭代都会增加 cnt,而实际上,当您低于 1/2 路点时,您不需要它。试试这个:(为了便于阅读,我重命名了一些变量。

rows = 10
var = ''
peak = int((rows + 1) / 2)
dec = 2
space = 2
count = 1
for row in range(1, rows + 1):
    if row <= peak:
        print(' ' * ((rows - 1) * 3) + str(row).zfill(2) + ' ' + var)
        var = str(row).zfill(2) + ' ' + var
        rows = rows-1
    else:
        print(' ' * ((rows * 2) + (peak + space)) + var[dec:])
        # print(' ' * ((rows * 2) + (peak + space) + count) + var[dec:])
        space = space + 2
        dec = dec + 2
        # cnt = cnt + 1

【讨论】:

  • 代码作为一些问题无法删除单个数字
【解决方案2】:

修复提供的代码看起来非常困难。 所以,在这里给我的代码,

>>> def f(n):
...     print('\n'.join(map(' '.join, [[f'{n-i:0>2d}' if i+1 > abs(n-j-1) else '  ' for i in range(n)] for j in range(2*n-1)])))
...
>>> f(5)
            01
         02 01
      03 02 01
   04 03 02 01
05 04 03 02 01
   04 03 02 01
      03 02 01
         02 01
            01

【讨论】:

    【解决方案3】:

    使用一些 f 字符串的非常不同的方法:

    def f(n):
        width = 3 * n - 1
        for i in range(1, n + 1):
            print(f'{" ".join(f"{j:02d}" for j in range(i, 0, -1)):>{width}s}')
        for i in range(n - 1, 0, -1):
            print(f'{" ".join(f"{j:02d}" for j in range(i, 0, -1)):>{width}s}')
    

    f(n=5) 然后输出:

                01
             02 01
          03 02 01
       04 03 02 01
    05 04 03 02 01
       04 03 02 01
          03 02 01
             02 01
                01
    

    f"{j:02d}" 使用 2 个字符和零填充打印整数 jf'{...:&gt;{width}s}' 是一个带有 width 字符的字符串,右对齐,没有填充。这些数字是使用range 对象生成的。

    如果在第一个循环中i=3,则打印语句中的range 对象将为range(3, 0, -1),即生成数字3, 2, 1join 使用" ".join(...) 和零填充将产生字符串"03 02 01"。然后这个字符串在f'{...:&gt;{width}s}'保留的width字符中右对齐。


    稍微优雅一点:

    from itertools import chain
    
    def f(n):
        width = 3 * n - 1
        for i in chain(range(1, n + 1), range(n - 1, 0, -1)):
            print(f'{" ".join(f"{j:02d}" for j in range(i, 0, -1)):>{width}s}')
    

    更新

    如果您希望这适用于超过 2 位的数字,您还必须参数化整数的宽度 i_width:

    from itertools import chain
    
    def f(n):
        i_width = len(str(n))
        width = (i_width + 1) * n - 1
        for i in chain(range(1, n + 1), range(n - 1, 0, -1)):
            print(f'{" ".join(f"{j:0{i_width}d}" for j in range(i, 0, -1)):>{width}s}')
    

    【讨论】:

    • :你能逐步解释一下这个方法看起来很独特,但没有得到你在做什么
    • 不打印预期输出
    • 你能在 google colab 中运行吗.. 我输入 n = 13 它没有给我正确的输出。它来了 ka 反向一些船 [海军舰艇]
    • 好的,显示 width 现在是从 n 计算出来的。 colab.research.google.com/drive/…
    • @hiro protagonist : 代码可能不适用于 3 位输入。尝试输入 n = 220
    【解决方案4】:

    您可以将结果存储到row&lt;breaking 之前,而不是为row&gt;breaking 提供或计算结果,然后为row&gt;breaking 弹出堆栈并打印结果

    n=13
    var=''
    breaking = int((n+1)/2)
    dec = 2
    space=2
    cnt=1
    stack =[]
    for row in range(1,n+1):
      if row <=breaking:
        x = ' ' * ( (n - 1) * 3 ) + str(row).zfill(2) + ' ' + var 
        print(x)
        if row!=breaking:
            stack.append(x)
        var = str(row).zfill(2) + ' ' + var 
        n = n-1
      else:
        if stack:
            print(stack.pop())
    

    【讨论】:

    • 您的代码不适用于 3 位数的值,因为您已将 zfill 设置为 2。将其设为通用。默认情况下应填充零以匹配 n 的长度。尝试输入 n = 220
    • @codeholic24 我拿了操作码并根据他的要求进行了修改
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多