【问题标题】:Separating Values from a file in Python在 Python 中从文件中分离值
【发布时间】:2021-08-29 15:46:53
【问题描述】:

假设我将这个 txt 文件格式化为(值)(空格)(值),并且有第二组数字用(制表符)分隔。这里给出了一个示例文件:

Header
5 5 6 7 8   7 8 9 0 1
7 6 3 4 1   1 3 6 8 1
8 7 4 1 3   1 9 8 5 1

现在我正在使用此代码打印 txt 文件中显示的所有值:

NEWLINE = "\n"

def readBoardFromFile():
    inputFileOK = False
    aBoard = []

    while (inputFileOK == False):
        try:
            inputFileName = input("Enter the name of your file: ")
            inputFile = open(inputFileName, "r")
            print("Opening File " + inputFileName + "for reading")

            currentRow = 0
            next(inputFile)

            for line in inputFile:
                aBoard.append([])

                for ch in line:
                    if (ch != NEWLINE):
                        aBoard[currentRow].append(ch)

                currentRow = currentRow + 1

            inputFileOK = True
            print("Completed reading of file " + inputFileName)

        except IOError:
            print("Error: File couldn't be opened")

    numRows = len(aBoard)
    numColumns = len(aBoard[0])

    return(aBoard,numRows,numColumns)

def display(aBoard, numRows, numColumns):

    currentRow = 0
    currentColumn = 0
    print("DISPLAY")

    while (currentRow < numRows):
        currentColumn = 0
        while (currentColumn < numColumns):
            print("%s" %(aBoard[currentRow][currentColumn]), end="")
            currentColumn = currentColumn + 1
        currentRow = currentRow + 1
        print()

    for currentColumn in range (0,numColumns,1):
        print("*", end ="")

    print(NEWLINE)

def start():
    aBoard,numRows,numColumns = readBoardFromFile()
    display(aBoard,numRows,numColumns)



start()

通常当我运行此代码时,这是输出:

DISPLAY
5 5 6 7 8       7 8 9 0 1
7 6 3 4 1       1 3 6 8 1
8 7 4 1 3       1 9 8 5 1
*******************

我怎样才能使输出为:

DISPLAY
5 5 6 7 8       
7 6 3 4 1       
8 7 4 1 3       

只显示左半边的数字?

【问题讨论】:

    标签: python arrays python-3.x list input


    【解决方案1】:

    也许您可以尝试使用 csv 模块并使用制表符分隔符打开文件。 然后假设您使用列表方法,您只能打印每行的第一个元素。

    类似:

    import csv
    with open("a.txt") as my_file:
    
        reader = csv.reader(my_file, delimiter ='\t')
    
        next(reader) # to skip header if exists
        for line in reader:
            print(line[0])
    

    【讨论】:

      【解决方案2】:

      据我所知,您没有在代码中考虑制表符,这可能是您在输出中包含其他字符的原因。

      这是我将采用的方法,在处理字符串时利用 Python 的强大功能。

      我会鼓励你在编写 Python 时使用这种方法,因为它会让你更容易喜欢。

      NEWLINE = "\n"
      
      def read_board_from_file():
          input_file_OK = False
          a_board = []
      
          while not input_file_OK:
              try:
                  input_file_name = input("Enter the name of your file: ")
      
                  with open(input_file_name, "r") as input_file:
                      # A file-like object (as returned by open())
                      # can be simply iterated 
                      for line in input_file:
      
                          # Skip header line if present
                          # (not sure how you would want to handle the
                          # header.
                          if "header" in line.lower():
                              continue
      
                          # Strip NEWLINE from each line,
                          # then split the line at the tab character.
                          # See comment above.
                          parts = line.strip(NEWLINE).split("\t")
      
                          # parts is a list, we are only interested
                          # in the first bit.
                          first_part = parts[0]
      
                          # Split the left part at all whitespaces.
                          # I'm assuming that this is what you want.
                          # A more complex treatment might make sense here,
                          # depending on your use-case.
                          entries = first_part.split()
      
                          # entries is a list, so we just need to append it
                          # to the board
                          a_board.append(entries)
      
                  input_file_OK = True
                  print(f"Completed reading of file {input_file_name}")
      
              except IOError:
                  print("Error: File {input_file_name} couldn't be opened.")
      
          return a_board
      
      def display_board(a_board):
          print("DISPLAY")
      
          longest_row = 0
      
          # a_board is a list of lists,
          # no need to keep track of the number of rows and columns,
          # we can just iterate it.
          for row in a_board:
              # row is a list of entries, we can use str.join() to add a space
              # between the parts and format the row nicely.
              row_str = " ".join(row)
      
              # At the same time we can keep track of the longest row
              # for printing the footer later.
              len_row_str = len(row_str)
              if len_row_str > longest_row:
                  longest_row = len_row_str
      
              print(row_str)
      
          # The footer is simply the asterisk character
          # printed as many times as the longest row.
          footer = "*" * longest_row
          print(footer, end="")
      
          print(NEWLINE)
      
      def start():
          a_board = read_board_from_file()
      
          display_board(a_board)
      
      start()
      

      【讨论】:

        【解决方案3】:

        我会在输入、输出和数据处理之间进行更多分离。您的输入是文件名,辅助输入是实际文件内容。数据处理步骤是获取文件内容,并返回一些板集合的内部表示。输出显示第一块板。

        from typing import Iterable, List
        
        def parse(lines: Iterable[str], board_sep: str = "\t") -> List[List[List[str]]]:
            boards = []
            for i, line in enumerate(lines):
                # list of the same line from each board
                board_lines = line.split(board_sep)
                if i == 0:
                    # this only happens once at the start
                    # each board can be a list of lists. so boards is a list of "list of lists"
                    # we're going to append lines to each board, so we need some initial setup
                    # of boards
                    boards = [[] for _ in range(len(board_lines))]
        
                for board_idx, board_line in enumerate(board_lines):
                    # then just add each line of each board to the corresponding section
                    boards[board_idx].append(board_line.split())
            return boards
        
        
        def show_board(board: List[List[str]]) -> None:
            for row in board:
                print(" ".join(row))
        

        现在我们可以将所有这些放在一起。我们需要:

        1. 获取文件名
        2. 打开文件
        3. 过滤掉“标题”和任何空行
        4. 将其余行传递给parse() 函数
        5. 获得第一块板
        6. 使用上下文打印它
        from typing import Tuple
        
        def get_board_dimensions(board: List[List[str]]) -> Tuple[int, int]:
            """ Returns a tuple of (rows, cols) """
            return len(board), len(board[0])
        
        
        def get_filtered_file(filename: str) -> Iterable[str]:
            with open(filename) as f:
                for line in f:
                    if not line or line.lower() == "header":
                        continue
                    yield line
        
        
        def main():
            filename = input("Enter the name of your file: ")
            filtered_lines = get_filtered_file(filename)
            boards = parse(filtered_lines)
        
            # now we can show the first one
            b = boards[0]
            _, cols = get_board_dimensions(b)
            print("DISPLAY")
            show_board(b)
            print("*" * (2 * cols - 1))  # columns plus gaps
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-01-25
          • 2018-01-15
          • 1970-01-01
          • 2015-03-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多