【问题标题】:How can I print strings based on ascending order of an index within a tuple如何根据元组中索引的升序打印字符串
【发布时间】:2026-01-12 13:50:01
【问题描述】:

我有 3 组学生成绩:group_a、group_b 和 group_c

每个组都包含一个按以下顺序排列的元组列表:(student_number,score)。

我想根据每个学生的分数打印一条消息:

  • A 组中的每个学生:“做得好学生{}。你的分数是 {}”
  • B 组中的每个学生:“干得好学生{}。你的分数是 {}”
  • C 组中的每个学生:“嗨,学生{}。你的分数是 {}。你可以做得更好。”

为了实现这一点,我在按元组的第一个元素对它们进行排序之前组合了所有 3 个组。

  all_groups = group_a + group_b + group_c
  
  # take first element for sort

  def takeFirst(elem):
    return elem[0] 

 #using the 'takeFirst' function, sort tuple based on the first element
  all_groups.sort(key=takeFirst)

#each tuple reflects (student number, score)
  print(all_groups)
 [(1, 29), (2, 54), (3, 52), (4, 50), (5, 30), (6, 57), (7, 56), (8, 47), (9, 51), (10, 55)]

接下来,我根据每个学生的分数打印了一条消息。

collection4 = []
collection5 = []
collection6 = []

for number, pair1 in enumerate(all_groups):
    # Unpack pair1: number, student_score
    student_number, score1 = pair1
    # print msg for each student. Attach every sentence into a 'collection' bucket.
    if score1 >=60:
        collection4.append('Well done student {}. Your score was {}.'.format(student_number, score1))
    elif score1 >=50 and score1<=59:
        collection5.append('Good work student {}. Your score was {}.'.format(student_number, score1))
    else:
        collection6.append('Hi student {}. Your score was {}. You can do better than this.'.format(student_number, score1))

接下来,我将集合 4、5 和 6 合并到一个桶中。

totalcollection = collection4 + collection5 + collection6

但是,当我打印 'totalcollection' 变量的内容时,结果不是按学号升序排列的。

我可以知道如何解决这个问题吗?谢谢。

【问题讨论】:

    标签: python function if-statement tuples


    【解决方案1】:

    问题出现在这里:

    totalcollection = collection4 + collection5 + collection6
    

    totalcollection 将首先添加collection4,然后是5 和6,但是假设如果id 为1 的学生没有在collection 4 中找到它的方式并最终在collection 6 中,那么它将在collection 4 中的所有结果之后添加到totalcollection并且已经添加了 5 个,这会打乱订单。

    一个简单的解决方案是只使用一个集合并附加其中的所有内容,以便对结果进行排序。

    totalcollection = []
    
    
    for number, pair1 in enumerate(all_groups):
        # Unpack pair1: number, student_score
        student_number, score1 = pair1
        # print msg for each student. Attach every sentence into a 'collection' bucket.
        if score1 >= 60:
            totalcollection .append(
                'Well done student {}. Your score was {}.'.format(student_number, score1))
        elif score1 >= 50 and score1 <= 59:
            totalcollection .append(
                'Good work student {}. Your score was {}.'.format(student_number, score1))
        else:
            totalcollection .append('Hi student {}. Your score was {}. You can do better than this.'.format(
                student_number, score1))
    

    【讨论】:

      【解决方案2】:

      您根据学生人数对所有内容进行了排序。然后你创建了子组 基于测试分数。那时,每个子组都按学生排序 数字。然后,您只需将基于测试分数的子组粘合在一起。有 没有理由期望结果组按学号排序—— 子组是根据不同的属性创建的。

      您可以通过使用更有意义的数据来简化事情。而不是原始元组, 考虑更多声明性选项,例如 namedtupledataclassattrs 班级。例如:

      from collections import namedtuple
      
      # The raw data.
      raw_data = [(1, 29), (3, 52), (2, 40), (4, 50), (7, 70), (5, 65), (6, 17)]
      
      # Create meaningful objects holding that information.
      TestResult = namedtuple('TestResult', 'student_number score')
      test_results = [TestResult(*tup) for tup in raw_data]
      
      # Tuples automatically sort by checking their first elements first.
      test_results.sort()
      

      如果你想生成消息,只需编写一个函数 TestResult 并返回消息。不要混在一起 具有其他问题的逻辑,例如遍历所有测试结果。

      def result_message(tr):
          fmt = (
              'Well done student {}. Your score was {}.' if tr.score >= 60 else
              'Good work student {}. Your score was {}.' if 50 <= tr.score <= 59 else
              'Hi student {}. Your score was {}. You can do better than this.'
          )
          return fmt.format(tr.student_number, tr.score)
      

      当您想要打印时,这很简单,您仍然可以获得所需的顺序:

      for tr in test_results:
          print(result_message(tr))
      

      【讨论】:

      • 谢谢@FMc。很高兴知道解决问题的另一种方法。