【问题标题】:How to find the second lowest lists into a nested list by their second value?如何通过第二个值将第二低的列表查找到嵌套列表中?
【发布时间】:2015-03-01 23:44:07
【问题描述】:

这里给出了一个嵌套列表:

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

现在我必须通过它们的第二个值在嵌套列表中找到第二低的列表。并将第二低的列表附加到另一个列表中。

所以输出应该是:

['Harsh', 20], ['Beria', 20]

我写了以下代码,但它不起作用:

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

result=[]

temp=max(nl, key=lambda x: x[1])

largest, larger = temp[1], temp[1]
for num in nl:
    if num[1] < largest:
        largest, larger = num[1], largest
    elif num[1] < larger:
        larger = num[1]
        result.append(larger)
print(result)

【问题讨论】:

  • 为什么它不起作用?错误?
  • 没有错误..它不会生成正确的输出。它只给出 [20,19]。
  • 这正是来自 HackerRank.com 的this question 类别/路径:Hackerrank.com -> 实践 -> Python -> 基本数据类型 -> 嵌套列表

标签: python list python-3.x nested-lists


【解决方案1】:

获取所有元素的min,使用该有效值进行过滤,然后获取剩余的最小值并保持元素等于剩余的最小值:

from operator import itemgetter
# min of all elements
mn = min(nl, key=itemgetter(1))[1]

# remove elements equal to min
filtered = [x for x in nl if x[1] != mn]

# get min of remaining
mn_fil = min(filtered,key=itemgetter(1))[1]

# filter remaining
out = [x for x in filtered if x[1] == mn_fil]
print(out)

[['Harsh', 20], ['Beria', 20]]

适用于您的两种情况:

In [19]: nl = [['Prashant', 32], ['Pallavi', 36], ['Dheeraj', 39], ['Shivam', 40]]    
In [20]: from operator import itemgetter    
In [21]: mn = min(nl, key=itemgetter(1))[1]    
In [22]: filtered = [x for x in nl if x[1] != mn]    
In [23]: mn_fil = min(filtered,key=itemgetter(1))[1]    
In [24]: out = [x for x in filtered if x[1] == mn_fil]    
In [25]: out
Out[25]: [['Dheeraj', 36]]

使用单个 for 循环,如果我们找到一个较低的元素,我们会从临时列表中删除所有元素,如果我们找到并且同样较低的元素,我们会追加它:

mn = min(nl, key=itemgetter(1))[1]
temp = []
best = float("inf")
for ele in nl:
    if mn < ele[1] < best:
        best = ele[1]
        temp = []
        out.append(ele)
    elif ele[1] == best:
        temp.append(ele)
print(temp)

【讨论】:

  • 您的代码没有为测试用例提供正确的输出 nl = [['Prashant', 32], ['Pallavi', 36], ['Dheeraj', 39], ['Shivam ', 40]] 。它给出 [['Dheeraj', 39]] 。但是输出应该是: [['Pallavi',36]]
  • @AbdullahAlImran,抱歉,您想要第二高,现在可以使用
  • 我想你没有注意到我要求第二低。不是第二高的。将最大值更改为最小值后,我得到了正确的输出。 :) 谢谢。
【解决方案2】:

我通过使用集合找到第二低的值,然后从列表中选择具有相同值的元素来做到这一点。

#ordering by value
nl.sort(key = lambda x: x[1])

values_set = set()
for value in nl:
    values_set.add(value[1])

values_list = list(values_set)
#ordering
values_list.sort()
#getting second lowest values
lowest_values = [lowest for lowest in nl if lowest[1] == values_list[1] ]

【讨论】:

    【解决方案3】:
    if __name__ == '__main__':
    arr = []
    for _ in range(int(input())):
        name = input()
        score = float(input())
        arr1 = [name, score]
        arr.append(arr1)
    arr.sort(key=lambda x: x[1])
    # print(arr)
    # print(min(arr,key=lambda x:x[1]))
    arr.remove(min(arr,key=lambda x:x[1]))
    # print(arr)
    minimum = min(arr,key=lambda x:x[1])
    # print(minimum[1])
    a=[]
    minimum = minimum[1]
    for i  in arr:
        if(i[1] == minimum):
            a.append(i[0])
    a.sort()
    for i in a:
        print(i)
    

    【讨论】:

    • 欢迎来到 SO!感谢您抽出宝贵时间回答这个问题。您能否提供有关您的解决方案的更多详细信息?为什么它比公认的答案更好?评论应该为您的解决方案提供更多见解。
    【解决方案4】:

    这是一个方便的小函数,它包含heapq.nlargest

    返回一个包含数据集中 n 个最大元素的列表


    import heapq
    num = heapq.nlargest(2, [key for item, key in nl])[-1]
    print [item for item in nl if item[-1] == num] #[['Harsh', 20], ['Beria', 20]]
    

    【讨论】:

    • 您的代码没有为测试用例提供正确的输出 nl = [['Prashant', 32], ['Pallavi', 36], ['Dheeraj', 39], ['Shivam ', 40]] 。它给出 [['Dheeraj', 39]] 。但是输出应该是: [['Pallavi',36]]
    • 帕拉维应该怎么样? 39 是 40 而不是 36 之后的第二大。
    【解决方案5】:

    你可以试试下面的代码。它工作正常。

    lst=[['Harry',37.21],['Berry',37.21],['Tina',37.2],['Akriti',41],['Harsh',39]]
    names=[]
    lowest = lst[0].__getitem__(1)
    second_lowest=0
    for l in lst:
        if l[1] < lowest:
            second_lowest = lowest
            lowest = l[1]
        elif l[1]<=second_lowest:
            second_lowest=l[1]
    for l in lst:
        if l[1]==second_lowest:
            names.append(l[0])
    
    
    print(lowest)
    print(second_lowest)
    print(names)
    

    【讨论】:

      【解决方案6】:
      if __name__ == '__main__':
      
          n = []
          s = []
          for _ in range(int(input())):
              name = input()
              n.append(name)
              score = float(input())
              s.append(score)
              
      data = [[x,y] for x,y in zip(n,s)]
      
      min_marks = min([x[1] for x in data])
      
      filtered_data = [d for d in data if d[1] != min_marks]
      
      sec_min = min([x[1] for x in filtered_data])
      
      students_with_sec_min_marks = sorted([d[0] for d in filtered_data if d[1] == sec_min])
      
      for s in students_with_sec_min_marks:
          print(s)
      

      【讨论】:

        【解决方案7】:
        if __name__ == '__main__':
            lst = []
            names = []
            for _ in range(int(input())):
                name = input()
                score = float(input())
                lst.append([name, score])
             
            lowest = max(lst, key=lambda x: x[1])[1]
            second_lowest=0
            for l in lst:
                if l[1] < lowest:
                    second_lowest = lowest
                    lowest = l[1]
                elif l[1] < second_lowest and l[1] != lowest:
                    second_lowest = l[1]
            for l in lst:
                if l[1] == second_lowest:
                    names.append(l[0])  
            
            names.sort()
            for nm in names:
                print(nm)
        

        【讨论】:

          【解决方案8】:

          我使用了下面的代码,效果很好:

          records = []
          
          if __name__ == '__main__':
              for i in range(int(input())):
                  name = input()
                  score = float(input())
                  records.append([name,score])
                  records.sort(key=lambda x:x[1])
              minimum = min(records,key=lambda x:x[1])
              minimum = minimum[1]
              args = records.copy()
              
              for i in args:
                  if(i[1] == minimum):
                      records.remove(i)
                  else:
                      continue
              
              minimum = min(records,key=lambda x:x[1])
              minimum = minimum[1]
              a=[]
              for i  in records:
                  if(i[1] == minimum):
                      a.append(i[0])
          
              a.sort()
              for i in a:
                  print(i)
          

          这样,您还可以删除多个相同的最低分数(如果它们存在)。在没有copy() 的情况下运行它并处理原始列表会导致循环错过几个相同的最低分数。

          【讨论】:

          • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
          【解决方案9】:

          您的示例可以简化为:

          second_lowest = sorted(set(v[1] for v in nl))[1]
          result = [v for v in nl if v[1] == second_lowest]
          print(result) # [['Harsh', 20], ['Beria', 20]]
          

          我使用您的一组值来找到第二个唯一的最低值。 除了拥有这个文件,在 nl 中找到与找到的值匹配的元素。

          【讨论】:

          • list(set(v[1] for v in nl))[1] 如何以任意顺序查找值?
          • print(set(v[1] for v in nl)) 的输出是set([19, 20, 21])。所以只取第二个值,这将是第二低的。
          • 是的,但绝对不能保证这个顺序,你认为为什么会有?
          • @PadraicCunningham 是正确的。 set 不保证集合元素会被排序。
          • 是的。你说得对。我添加了对集合的排序以确保其排序:-) 与 c++ 中的集合混淆了。
          【解决方案10】:

          我遇到过类似的问题,在参考了这个页面后,我得到了一些想法并能够解决它。

          nl = [['Harsh', 20], ['Beria', 20], ['Varun', 19], ['Kakunami', 19], ['Vikas', 21]]
          
          second = max(nl, key= lambda x: x[1])[1]
          first = min(nl, key= lambda x: x[1])[1]
              
          for i in range(len(nl)):
              if nl[i][1] <= second and nl[i][1] != first:
                  second = nl[i][1]
              
          for i in range(len(nl)):
              if second == nl[i][1]:
                  print(nl[i], end=", ")
          

          【讨论】:

          • 这个答案有一些解释会更好,尤其是它与其他答案的不同之处。
          猜你喜欢
          • 1970-01-01
          • 2011-06-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-29
          • 2018-05-08
          • 1970-01-01
          相关资源
          最近更新 更多