【问题标题】:Nested List HackerRank Issue in Passing all 10 Tests通过所有 10 项测试的嵌套列表 HackerRank 问题
【发布时间】:2020-05-23 00:08:26
【问题描述】:

给定物理课学生中每个学生的姓名和成绩,将它们存储在嵌套列表中,并打印任何成绩第二低的学生的姓名。

注意:如果有多个年级相同的学生,请按字母顺序排列他们的姓名并将每个姓名打印在新行上。

输入格式

第一行包含一个整数,学生人数。 随后的几行逐行描述了每个学生;第一行包含学生的姓名,第二行包含他们的成绩。

约束

总会有一名或多名学生成绩倒数第二。

输出格式

打印物理成绩第二低的任何学生的姓名;如果有多个学生,请按字母顺序排列他们的姓名,并将每个学生都打印在新行上。

示例输入

5
Harry
37.21
Berry
37.21
Tina
37.2
Akriti
41
Harsh
39

样本输出

Berry
Harry

这是我解决问题的代码:

    if __name__ == '__main__':

       list = []
       for _ in range(int(input())):
          name = input()
          score = float(input())

          #list = []

          list.append([name, score])

          #print(list)
       list.sort(key = lambda x: float(x[1]))
       #print(list)

       new_lst = []

       for i in range(len(list)):
          for j in range(1):
              if list[i][1] == list[1][1]:
                  new_lst += [list[i][0]]
       #print(new_lst)
        sorted_lst = sorted(new_lst)
       #print(sorted_lst)


       for student in sorted_lst:
           print(student)

10 个测试用例(测试 2 和 3)中有 2 个代码失败。以下是测试 2 和 3 的情况:

样本输入(测试 2)

5
Harsh
20
Beria
20
Varun
19
Kakunami
19
Vikas
21

样本输出(测试 2)

Beria
Harsh

样本输入(测试 3)

4
Rachel
-50
Mawer
-50
Sheen
-50
Shaheen
51

样本输出(测试 3)

Shaheen

但是,我无法弄清楚为什么这 2 个测试用例不起作用,因为我认为我已经很好地涵盖了边界测试用例。尽管包括上面的第一个测试用例,但我的代码确实通过了 10 次测试中的 8 次。

我有什么遗漏吗?

编辑

我想出了一个方法来通过剩下的测试用例(我修改过的代码):

    if __name__ == '__main__':

        lst = []
        for _ in range(int(input())):
            name = input()
            score = abs(float(input()))

            #lst = []

            lst.append([name, score])

            #print(lst)
        lst.sort(key = lambda x: float(x[1]))
        #print(lst)

        #lst.remove(min(lst))
        #print(lst)

        new_lst = []

        min_mark = lst[0][1]
        count = 0

        for i in range(len(lst)):
            if min_mark == lst[i][1]:
            count = count+1

        if count > 1:
            for j in range(count - 1):
            lst.pop(0)
            #print(lst)

        for i in range(len(lst)):
            for j in range(1):
                if lst[i][1] == lst[1][1]:
                    new_lst += [lst[i][0]]

        #print(new_lst)
        sorted_lst = sorted(new_lst)
        #print(sorted_lst)

        for student in sorted_lst:
            print(student)

您如何看待这个最终代码?够好吗?还是应该缩短?

【问题讨论】:

  • 我认为您还没有充分涵盖“所有”边缘情况。你假设第二低的成绩将是排序列表中的第二项(即你总是假设list[1][1] 是第二低的——这就是你无法通过测试的地方。提示:最低成绩也可能是两倍,然后你的第二低成绩实际上可能是指数!= 1 ;)
  • 另外,不要将名称 list 用于您的变量。您正在覆盖 Python 提供的 list 函数。
  • @DewMan 我发布我的答案只是尝试一下,因为这两个答案都通过了我提交的所有案例。

标签: python nested-lists


【解决方案1】:

使用heapitertools.groupby 的一种可能实现:

from heapq import heappush, heappop
from itertools import groupby

n = int(input())

heap = []
for i in range(n):
    name = input()
    score = float(input())

    heappush(heap, (score, name))

grouper = groupby((heappop(heap) for _ in range(len(heap))), key=lambda k: k[0])
next(grouper)  # skip lowest score
print(*(v for _, v in next(grouper)[1]), sep="\n")  # print second lowest group

【讨论】:

  • 这看起来很新鲜 我也以多种方式完成了这个挑战,但这是不同的。
【解决方案2】:

重用您现有的大部分代码,您可以像这样更“逐步”地解决它:

if __name__ == '__main__':

       score_list = []
       for _ in range(int(input())):
          name = input()
          score = float(input())
          score_list.append([name, score])

       score_list.sort(key = lambda x: float(x[1]))
       min_score = score_list[0][1]

       # remove the minimum score entries
       score_list = list(filter(lambda x: x[1] != min_score, score_list))

       second_min_score = score_list[0][1] #since the minimum were removed

       # keep the second minimum score entries
       score_list = list(filter(lambda x: x[1] == min_score, score_list))

       # sort the names alphabetically, if there are multiple entries
       score_list.sort(key = lambda x: x[0])

       for student in score_list:
               print(student[0]) 

【讨论】:

    【解决方案3】:

    我可能会采取简单的三步法。

    (注意:我已将 list 更改为 list_,因为使用保留关键字通常不是一个好主意。)

    假设您的学生列表如下所示:

    测试 2:

    [
         ['Harsh', '20'],
         ['Beria', '20'],
         ['Varun', '19'],
         ['Kakunami', '19'],
         ['Vikas', '21']
    ]
    

    测试 3:

    [
       ['Rachel', '-50'],
       ['Mawer', '-50'],
       ['Sheen', '-50'],
       ['Shaheen', '51']
    ]
    

    1 - 获得最低总分

    min_grade = min([list_[i][1] for i in range(len(list_))])
    

    2 - 获得高于我们最初最低成绩的最低成绩

    next_min_grade = min([list_[i][1] for i in range(len(list_)) if list_[i][1]  > min_grade])
    

    3 - 生成分数次低的学生列表

    next_min_students = [list_[i][0] for i in range(len(list_)) if list_[i][1] == next_min_grade]
    

    您可以使用.join() 函数和换行符 (\n) 输出。

    print("\n".join(next_min_students))
    

    测试 2:

    Harsh
    Beria
    

    测试 3:

    Shaheen
    

    【讨论】:

      【解决方案4】:

      我用两个黑客级别的实现来回答这个问题。

      • 首次使用set实现
          if __name__ == '__main__':
          stu_list = [[input(), float(input())] for _ in range(int(input()))]
          # _[1] : it takes 1st arguments from all nested lists of stu_list
          # last [1] takes secondLowestGrade from set
          # sec_lowest_grade = sorted(set(_[1] for _ in stu_list))[1]
          print("\n".join(sorted(_[0] for _ in stu_list if _[1] == sorted(set(_[1] for _ in stu_list))[1])))
      
      • 不使用 set 的第二次实施
          from operator import itemgetter
          main_lst = []
          for _ in range(int(input())):
              main_lst.append([input(),float(input())])
          main_lst.remove(min(main_lst,key=itemgetter(1)))
          temp_list = []
          min_list = min(main_lst,key=itemgetter(1))
          for i in main_lst:
              if i[1] == min_list[1]:
                  temp_list.append(i)
          for i in sorted(temp_list,key=itemgetter(0)):
              print(i[0])
      
      • @DewMan 我提交了两个解决方案,它通过了所有测试用例。试着告诉我它是否适合你。

      【讨论】:

        【解决方案5】:

        我认为您对答案感到满意,但我有一个稍微不同的解决方案,我想分享一下。希望这也有帮助。在 Python3 中:

        if __name__ == '__main__':
        n = int(input())
        students = [[input(), float(input())] for _ in range(n)]
        
        students.sort(key=lambda gr: (gr[1], gr[0]))
        grade = [i[1] for i in students]
        names = [i[0] for i in students]
        
        seclowValue = sorted(set(grade))[1]
        
        for x in range(len(grade)):
            if grade[x] == seclowValue:
                print(names[x])
        

        【讨论】:

          【解决方案6】:

          以下代码也可以解决问题!

          if __name__ == '__main__':
              l= []
              l2 = []
              for _ in range(int(input())):
                  name = input()
                  score = float(input())
                  l.append(list([name, score]))
              #print(l)
              lsort = sorted(l, key=lambda x: (x[1], x[0]))
              #print(lsort)
              # following only addresses only the max value of all and ot
              # a list of those with max scores 
              for i in range(len(lsort)):
                      if lsort[i][1] != max(lsort, key=lambda x: x[1])[1]:
                          #print(lsort[i])
                          l2.append(lsort[i])
              #print(l2)
              for i in range(len(l2)):
                      if l2[i][1] == max(l2, key=lambda x: x[1])[1]:
                          print(l2[i][0])

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-01-19
            • 2017-05-16
            • 2011-04-08
            • 2019-12-10
            • 2022-08-08
            • 1970-01-01
            相关资源
            最近更新 更多