代码之家  ›  专栏  ›  技术社区  ›  Christina Wurschum

为什么For循环只迭代一次?

  •  0
  • Christina Wurschum  · 技术社区  · 2 年前

    我需要在StudentInfo.tsv中获取这些信息:

    Barrett    Edan    70  45  59
    
    Bradshaw    Reagan  96  97  88
    Charlton    Caius   73  94  80
    Mayo    Tyrese  88  61  36
    Stern    Brenda  90  86  45
    

    并将其输出到另一个文件,如下所示:

    Barrett    Edan    70  45  59  F
    Bradshaw    Reagan  96  97  88  A
    Charlton    Caius   73  94  80  B
    Mayo    Tyrese  88  61  36  D
    Stern    Brenda  90  86  45  C
    
    Averages: midterm1 83.40, midterm2 76.60, final 61.60
    

    这就是我重写学生信息并添加字母等级的要点。然而,for循环并没有按我需要的方式运行。

    我得到的输出是“[]”

    import csv
    
    def calculate_grade(average_score):
      if average_score >= 90:
          return 'A'
      elif 80 <= average_score < 90:
          return 'B'
      elif 70 <= average_score < 80:
          return 'C'
      elif 60 <= average_score < 70:
          return 'D'
      else:
          return 'F'
    
    tsv_input = str(input())
    student_data = []
    
    
    with open(tsv_input) as file_a:
        tsv_read = file_a.readlines()
        
        for row in tsv_read:
            student_data = [row.strip().split('\t')]
    
    with open('report.txt', 'a+') as final_file:
        for info in student_data:
            last_name, first_name, midterm1, midterm2, final = info
            average_score = (float(midterm1) + float(midterm2) + float(final)) / 3
            
            final_grade = calculate_grade(average_score)
            
            final_file.write(f'{last_name}\t{first_name}\t{midterm1}\t{midterm2}\t{final}\{final_grade}\n')
        final_read = final_file.readlines()
        print(final_read)
    
    3 回复  |  直到 2 年前
        1
  •  1
  •   S.B Daniel Pryden    2 年前

    更改行:

    student_data = [row.strip().split('\t')]
    

    student_data.append(row.strip().split("\t"))
    

    你不想分配 student_data 添加到新的内容,但却将拆分的行添加到其中。

        2
  •  1
  •   ouroboros1    2 年前

    您的代码有三个问题:

    1. 正如您在中所指出的 comments ,并且在 answer 通过 @S.B ,您正在覆盖 student_data 每次使用最后一行的输入,而不是使用添加 list.append :
    student_data = []
    
    with open(tsv_input) as file_a:
        tsv_read = file_a.readlines()
        
        for row in tsv_read:
            # Issue 1: use: `list.append`
            # student_data = [row.strip().split('\t')]
            student_data.append(row.strip().split('\t'))
    
    1. (次要)你在中有一个打字错误 final_file.write(...) :
            # Issue 2 (typo)
            # change `\{final_grade}` -> `\t{final_grade}`
            final_file.write(f'{last_name}\t{first_name}\t{midterm1}\t{midterm2}\t{final}\t{final_grade}\n')
    
    1. final_file.readlines() 返回一个空列表。这是对使用含义的误解 open 在模式中 a+ 。来自 BSD fopen manpage 在下面 查阅 here ):

    开放阅读和写作。如果文件不存在,则会创建该文件。 流位于文件的末尾。 [添加斜体字]

    也就是说,当你打电话的时候 f.readlines ,文件的光标为 在文件的末尾 ,自然导致一个空 list :那里什么都没有。

    为了获得所需的结果,您首先需要返回到文件的开头。您可以使用 f.seek 为此:

        # Issue 3 (reset cursor to start file, i.e. `0`)
        final_file.seek(0)
        final_read = final_file.readlines()
        print(final_read)
    

    打印

    ['Barrett\tEdan\t70\t45\t59\tF\n', 
     'Bradshaw\tReagan\t96\t97\t88\tA\n', 
     'Charlton\tCaius\t73\t94\t80\tB\n', 
     'Mayo\tTyrese\t88\t61\t36\tD\n', 
     'Stern\tBrenda\t90\t86\t45\tC\n']
    
        3
  •  0
  •   SIGHUP    2 年前

    为了让你得出最终的平均值,你需要不断地计算总数。您还需要说明输入中的空行。每条线路 必须 正好有5个代币。

    INFILE = "foo.tsv"
    OUTFILE = "report.txt"
    
    grade_map = {
        90: "A",
        80: "B",
        70: "C",
        60: "D"
    }
    
    def calculate_grade(n):
        for k, v in grade_map.items():
            if n >= k:
                return v
        return "F"
    
    
    totals = [0, 0, 0]
    n = 0
    
    with open(INFILE) as data, open(OUTFILE, "w") as output:
        for line in data:
            tokens = line.split()
            if len(tokens) == 5: # sanity check
                n += 1
                values = list(map(int, tokens[2:]))
                for i, v in enumerate(values):
                    totals[i] += v
                tokens.append(calculate_grade(sum(values) / len(values)))
                print(" ".join(tokens), file=output)
    
        averages = [total / n for total in totals]
    
        print(f"Averages: midterm1 {averages[0]:.2f}, midterm2 {averages[1]:.2f}, final {averages[2]:.2f}", file=output)