【问题标题】:Python: How to print a 5x5 grid on the same line as anotherPython:如何在与另一行相同的行上打印 5x5 网格
【发布时间】:2025-12-01 13:45:02
【问题描述】:

我正在尝试构建一个通过命令行以大文本形式打印给定字符串的函数。每个字母都是由 * 和空格组成的 5x5 网格。如何在与前一个相同的行上打印下一个 5x5 字符以打印出给定的字符串?

代码:

    options = {
    'a': '  *  \n * * \n*****\n*   *\n*   *', 
    'b': '**** \n*   *\n*****\n*   *\n**** ',
    'c': ' ****\n*    \n*    \n*    \n ****',
    'd': '**** \n*   *\n*   *\n*   *\n**** ',
    'e': '*****\n*    \n*****\n*    \n*****',
    'f': '*****\n*    \n*****\n*    \n*    ',
    'g': '*****\n*    \n* ***\n*   *\n*****',
    'h': '*   *\n*   *\n*****\n*   *\n*   *',
    'i': '*****\n  *  \n  *  \n  *  \n*****',
    'j': '***  \n  *  \n  *  \n  *  \n***  ',
    'k': '*   *\n* *  \n*    \n* *  \n*   *',
    'l': '*    \n*    \n*    \n*    \n*****',
    'm': '*   *\n** **\n* * *\n*   *\n*   *',
    'n': '*   *\n**  *\n* * *\n*  **\n*   *',
    'o': ' *** \n*   *\n*   *\n*   *\n *** ',
    'p': '**** \n*   *\n**** \n*    \n*    ',
    'q': ' *** \n*   *\n* * *\n*  * \n ** *',
    'r': '**** \n*   *\n**** \n* *  \n*  **',
    's': ' ****\n*    \n *** \n    *\n**** ',
    't': '*****\n  *  \n  *  \n  *  \n  *  ',
    'u': '*   *\n*   *\n*   *\n*   *\n *** ',
    'v': '*   *\n*   *\n * * \n * * \n  *  ',
    'w': '*   *\n*   *\n* * *\n* * *\n * * ',
    'x': '*   *\n * * \n  *  \n * * \n*   *',
    'y': '*   *\n * * \n  *  \n  *  \n  *  ',
    'z': '*****\n   * \n  *  \n *   \n*****',
    ',': '     \n     \n   **\n   **\n  *  ',
    ':': '     \n  *  \n     \n  *  \n     '

    }

    def Print_Big(inputString):
        lst = list(inputString)
        for i in lst:
            print(options[i], end = "")

    while True:
        userIn = input('Please enter a letter to big-ify: ').lower()
if userIn == "exit":
    break
elif userIn != "" and len(userIn) >= 1:
    Print_Big(userIn)
else:
    print('Please enter a valid string')

【问题讨论】:

    标签: python printing formatting


    【解决方案1】:

    您不能并排打印不同的字母,因为您制作的每个字母中都有 \n(换行符)。 因此,默认情况下,每个下一个元素都将打印在下一行。 现在为了克服这个问题,我对您的代码进行了一些更改。 在代码中为每个字母制作一个列表字典,如下所示。

    options = {
            'a':['  *  ',' * * ','*****','*   *','*   *'],
            'b':['**** ','*   *','*****','*   *','**** '],
            'c':[' ****','*    ','*    ','*    ',' ****'],
             ........
            }
    

    为什么是列表字典?因为我现在可以逐行访问一个字母的每一行。 我在这里给出了代码示例。它适用于 3 个字符 a、b、c,因为我在 dict 中仅添加了 3 个字母以进行演示。

    options = {         
            'a':['  *  ',' * * ','*****','*   *','*   *'],
            'b':['**** ','*   *','*****','*   *','**** '],
            'c':[' ****','*    ','*    ','*    ',' ****']
            }   # I added only 3 letters, so It will work for only(a,b,c)
    
    def Print_Big(newList):
        for i in range(len(options['a'])):  
            for j in range(len(newList)):       
                print(options[newList[j]][i]+"   ",end = " ")
            print()
    

    输出:

    Please enter a letter to big-ify: abc
        *      ****      ****
       * *     *   *    *
      *****    *****    *
      *   *    *   *    *
      *   *    ****      ****
    

    【讨论】:

    • 哇,谢谢你的详细回答。这太棒了,我没有考虑单独的字符串。对于像我这样的 python 初学者,我希望你的例子能有更多的问题:)
    【解决方案2】:

    @Mufeed 的回答非常好,非常适合初学者。这个答案有点复杂。

    我建议的一件事是使用 Python 的多行字符串来编写您的信件。它使它们更容易编辑。我的字母有点大,我只定义了三个字母 b、g 和 i(在 emacs 中使用艺术家模式..):

    letter_definitions = {
        'b': Letter("""
          ****************
          ******************
          *****          *****
          ***              ***
          ***              ****
          ***              ****
          ***            ******
          ******************
          *********************
          ***             * *****
          ***               ******
          ***                 *****
          ***                  ****
          ***                  ****
          ***                  ****
          ***                ****
          ***          **********
          *********************
          *****************
            """),
        'g': Letter("""
                   ****************
                 *** *        **** **
                ***              *****
             ****
            ****
           *****
           ****
           ****
           ****            ************
           ****            *************
           *****                       *
           *****                       *
            *****                     **
             ******                   *
               *******               **
                 *********       *****
                       *************
             """),
        'i': Letter("""
            +---+
            |***|
            +---+
    
             +-+
             |*|
             |*|
             |*|
             |*|
             |*|
             |*|
             +-+
        """),
    }
    

    Letter 类存储形状,记录高度/宽度/基线(__init__ 方法),并且可以将自身写入二维缓冲区(add_to_buffer() 方法):

    import textwrap
    
    class Letter(object):
        def __init__(self, shape):
            # remove space to the left (textwrap.dedent)
            # and split the shape string into lines (self.shape is a list of strings)
            self.shape = textwrap.dedent(shape).split('\n')
    
            # remove any initial empty lines
            while self.shape[0] == '':
                self.shape = self.shape[1:]
    
            # remove any trailing empty lines
            while self.shape[-1] == '':
                self.shape = self.shape[:-1]
    
            self.height = len(self.shape)
            self.width = max(len(line) for line in self.shape)
    
            # we're doing the easy case where all letters are capitals
            # and the baseline is at the bottom
            self.baseline = self.height
    
        def add_to_buffer(self, buffer, x, y):
            "Write this letter shape to a 2-dimensional buffer at position x, y."
    
            # justify our baseline with the buffer's baseline
            y += buffer.baseline - self.baseline  
    
            # keeping track of which line and character we're at,
            # we go through each line in the shape
            for lineno, line in enumerate(self.shape):
                # .. and each character in the line
                for charpos, ch in enumerate(line):
                    # and put the character into the buffer
                    buffer[x + charpos, y + lineno] = ch
    

    缓冲区在TextLine 类中实现,它通过询问每个字母的高/宽来创建足够大小的(模拟的)二维缓冲区来容纳所有字母形状:

    class TextLine(object):
        def __init__(self, letters):
            self.letters = letters
            self.width = sum(letter.width for letter in self.letters)
            # one space between each letter, except the last one
            self.width += len(self.letters) - 1
            self.height = max(letter.height for letter in self.letters)
            self.baseline = self.height
    
            # add letters to buffer
            self.buffer = [' '] * (self.width * self.height)  # should probably use a buffer.buffer here..
            x = 0
            for letter in self.letters:
                letter.add_to_buffer(self, x, 0)
                x += letter.width + 1
    
        def __setitem__(self, (x, y), ch):
            # calculate the position and assign the character
            self.buffer[y * self.width + x] = ch
    
        def __str__(self):
            chunks = []
            # divide the buffer into pieces/chunks of length self.width..
            # (see https://*.com/a/312464/75103 for how this works)
            for i in range(0, len(self.buffer), self.width):
                chunk = self.buffer[i:i + self.width]
                chunks.append(''.join(chunk))
            # .. and start each chunk on a new line
            return '\n'.join(chunks)
    

    最后我将 print_big() 函数重命名为 big_text() 并返回要打印的字符串:

    def big_text(text):
        lines = text.splitlines(False)  # don't keep newlines
        res = []
        for line in lines:
            # convert each character to the corresponding Letter
            letters = [letter_definitions[ch] for ch in line]
            # put the letters into a TextLine
            text_line = TextLine(letters)
            # and append the buffer to the result
            res.append(str(text_line))
        return '\n\n'.join(res)
    

    很多时候你需要重用这些函数,如果它们返回字符串而不是打印它,那么重用它们会更容易,而且你可以像打印一样简单地使用它:

    print big_text('big')
    

    结果:

    ****************                                             
    ******************                                           
    *****          *****                    ****************     
    ***              ***                  *** *        **** **   
    ***              ****                ***              *****  
    ***              ****             ****                       
    ***            ******            ****                        
    ******************        +---+ *****                        
    *********************     |***| ****                         
    ***             * *****   +---+ ****                         
    ***               ******        ****            ************ 
    ***                 *****  +-+  ****            *************
    ***                  ****  |*|  *****                       *
    ***                  ****  |*|  *****                       *
    ***                  ****  |*|   *****                     **
    ***                ****    |*|    ******                   * 
    ***          **********    |*|      *******               ** 
    *********************      |*|        *********       *****  
    *****************          +-+              *************    
    

    【讨论】:

      最近更新 更多