How to find the second lowest lists into a nested list by their second value?
Question:
Here is given a nested list:
nl = [['Harsh', 20], ['Beria', 20], ['Varun', 19], ['Kakunami', 19], ['Vikas', 21]]
Now I have to find the second lowest lists into the nested list by their second value. And append the second lowest lists into another list.
So the output should be:
['Harsh', 20], ['Beria', 20]
I wrote the following code but it doesn’t work:
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)
Answers:
Here is a handy little function that incorporates heapq.nlargest
:
Return a list with the n largest elements from the dataset
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]]
Your example can be simplified into this:
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]]
I use set of your values to find second, unique lowest value.
Than having this file, find elements in nl that match the found value.
Get the min
of the total elements, filter using that valid then get min of remaining and keep elements equal to min of remaining:
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]]
Works for both your cases:
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]]
Using a single for loop we remove all elements from the temp list if we find a lower element, if we find and equally lower one we append it:
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)
I did it by finding the second lowest value using a set and then selecting elements from the list with the same value.
#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] ]
You can try below code. It works fine.
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)
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)
I have come across similar kind of problem and after referring this page I got some ideas and able to solve it.
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=", ")
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)
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)
I used the below code and it worked good:
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)
This way, you will also be able to remove multiple same lowest scores if they exist. Running it without copy()
and working on the original list causes the loop to miss the several same lowest scores.
students=[]
if __name__ == '__main__':
for _ in range(int(input())):
name = input()
score = float(input())
students.append([name,score])
students.sort(key=lambda x:x[1] )
students.remove(min(students,key=lambda x:x[1] ))
names=[]
score=students[0][1]
for student in students:
if student[1]==score:
names.append(student[0])
names.sort()
for each in names:
print(each)
Here is given a nested list:
nl = [['Harsh', 20], ['Beria', 20], ['Varun', 19], ['Kakunami', 19], ['Vikas', 21]]
Now I have to find the second lowest lists into the nested list by their second value. And append the second lowest lists into another list.
So the output should be:
['Harsh', 20], ['Beria', 20]
I wrote the following code but it doesn’t work:
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)
Here is a handy little function that incorporates heapq.nlargest
:
Return a list with the n largest elements from the dataset
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]]
Your example can be simplified into this:
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]]
I use set of your values to find second, unique lowest value.
Than having this file, find elements in nl that match the found value.
Get the min
of the total elements, filter using that valid then get min of remaining and keep elements equal to min of remaining:
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]]
Works for both your cases:
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]]
Using a single for loop we remove all elements from the temp list if we find a lower element, if we find and equally lower one we append it:
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)
I did it by finding the second lowest value using a set and then selecting elements from the list with the same value.
#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] ]
You can try below code. It works fine.
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)
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)
I have come across similar kind of problem and after referring this page I got some ideas and able to solve it.
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=", ")
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)
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)
I used the below code and it worked good:
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)
This way, you will also be able to remove multiple same lowest scores if they exist. Running it without copy()
and working on the original list causes the loop to miss the several same lowest scores.
students=[]
if __name__ == '__main__':
for _ in range(int(input())):
name = input()
score = float(input())
students.append([name,score])
students.sort(key=lambda x:x[1] )
students.remove(min(students,key=lambda x:x[1] ))
names=[]
score=students[0][1]
for student in students:
if student[1]==score:
names.append(student[0])
names.sort()
for each in names:
print(each)