티스토리 뷰

728x90

Nested Lists

Given the names and grades for each student in a class of N students, store them in a nested list and print the name(s) of any student(s) having the second lowest grade.

Note: If there are multiple students with the second lowest grade, order their names alphabetically and print each name on a new line.

Example

records = [["chi", 20.0], ["beta", 50.0], ["alpha", 50.0]]

The ordered list of scores is [20.0, 50.0], so the second lowest score is 50.0. There are two students with that score: ["beta", "alpha"]. Ordered alphabetically, the names are printed as:

alpha
beta

Input Format

The first line contains an integer, N, the number of students.
The 2N subsequent lines describe each student over 2 lines.
- The first line contains a student's name.
- The second line contains their grade.

Constraints

  • 2 <= N <= 5
  • There will always be one or more students having the second lowest grade.

Output Format

Print the name(s) of any student(s) having the second lowest grade in. If there are multiple students, order their names alphabetically and print each one on a new line.

Sample Input 0

5
Harry
37.21
Berry
37.21
Tina
37.2
Akriti
41
Harsh
39

Sample Output 0

Berry
Harry

 

문제해석

1. input으로 학생수를 나타내는 N값과 학생의 이름인 name, 학생의 점수인 score가 입력된다.

2. 입력된 학생의 score 중 두 번째로 점수가 낮은 학생의 이름을 출력한다.

3. 만약 동일한 점수의 학생이 여러 명 있다면 이름은 알파벳 순으로 출력한다.

 

문제풀이

파이썬을 잘 몰라서 한참 고생했다... 이 방법이 효율적인지 아닌지도 잘 모르겠다...;;; 작성한 방법은 아래와 같다.

 

0. 입력되는 name, score 값을 arrlist라는 list 변수에 추가한다.

   arrlist에는 input으로 입력된 모든 값이 저장되어 있다. 

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

1. 리스트에서 2번째로 작은 값을 가져오는 방법으로 1번째로 작은 값을 제거하는 방법을 선택했다.

   그래서 min()함수를 사용하여 가장 작은 값을 가져와서 min1stValue 변수에 저장한다.

   이 때, min(arrlist, key=lambda x: x[1]) 이렇게만 하면 배열의 첫 번째 값인 name이 출력된다.

   그래서 뒤에 [1]을 붙여 min(arrlist, key=lambda x: x[1])[1] 이라고 명시해야 한다.

#1. get 1st min value        
    min1stValue = min(arrlist, key=lambda x: x[1])[1]
    #print("min1stValue: {0}".format(min1stValue))

2. 이제 arrlist 리스트의 2번째 인자?값을 모두 체크하여 min1stValue가 아닌 값만을 가져와서 retlist에 저장한다.

   (원래는 remove하는 방법으로 하였으나 이렇게 하니까 list의 len값이 계속 바껴서 에러가 발생하였다.)

   while문을 사용하는 이유는 가장 작은 값인 사람이 여러 명 있을 수 있기 때문이다.   

#2. create list not min value data
    i = 0
    while i < len(arrlist):
        if arrlist[i][1] != min1stValue:
            retlist.append(arrlist[i])
        i += 1

3. 최소값을 제거한 retlist 리스트에서 다시 min값을 찾으면 원하는 2번째로 작은 값을 찾을 수 있다.

#3. get 2nd min value
    min2ndValue = min(retlist, key=lambda x: x[1])[1]

4. retlist에서 가장 작은 값을 가지고 있는 이름만을 가져와서 namelist에 다시 저장한다.

   while문을 사용하는 이유는 2번과 동일하게 최소값인 사람이 여러 명 있을 수 있기 때문이다.

#4. get final name value 
    i = 0
    while i < len(retlist):        
        if retlist[i][1] == min2ndValue:
            namelist.append(retlist[i][0])          
        i += 1

5. 최소값인 사람이 여러 명 있을 경우 name 값으로 정렬하여 출력하여야 하므로, sort() 함수를 사용하여 정렬을 하였다.

   그리고 그냥 출력할 경우 list 형식으로 결과가 나오므로 while문을 사용하여 이름만 출력하도록 하였다.

#5. sort name list and print result name
    namelist.sort()
    i = 0
    while i < len(namelist):
        print(namelist[i])
        i += 1

 

최종코드

if __name__ == '__main__':
    arrlist = []
    retlist = []
    namelist = []
    
    for _ in range(int(input())):
        name = input()
        score = float(input())
        
        tmplist = [name, score]
        arrlist.append(tmplist)
    

    #1. get 1st min value        
    min1stValue = min(arrlist, key=lambda x: x[1])[1]
    #print("min1stValue: {0}".format(min1stValue))
    
    #2. create list not min value data
    i = 0
    while i < len(arrlist):
        if arrlist[i][1] != min1stValue:
            retlist.append(arrlist[i])
        i += 1

    #3. sort asc list and get 2nd min value
    sort_arrlist = sorted(retlist, key=lambda x:x[1])  
    min2ndValue = min(sort_arrlist, key=lambda x: x[1])[1]
    
    #4. get final name value 
    i = 0
    while i < len(sort_arrlist):        
        if sort_arrlist[i][1] == min2ndValue:
            namelist.append(sort_arrlist[i][0])          
        i += 1
    
    #5. print result name
    namelist.sort()
    i = 0
    while i < len(namelist):
        print(namelist[i])
        i += 1
        
        

Discussions

아래처럼 주요 구문은 단 2줄로 구현이 가능하였다...ㅠ.ㅠ (대단함...!!)
if __name__ == '__main__':
    marksheet = []

    for _ in range(int(input())):
        name = input()
        score = float(input())
        
        marksheet.append([name, score])
        
    second_highest = sorted(list(set([score for name, score in marksheet])))[1]
    print('\n'.join([a for a,b in sorted(marksheet) if b == second_highest]))

구문별로 실행하면서 코드를 분석해 보았다.

 

1. 첫 번째로 입력된 input 값을 저장한 marksheet 값을 출력해 보았다.

   샘플 데이터 5개가 입력된 것을 확인할 수 있다.

   결과값: [['Harry', 37.21], ['Berry', 37.21], ['Tina', 37.2], ['Akriti', 41.0], ['Harsh', 39.0]]

print(marksheet)

2. marksheet 리스트에서 name, score 값 중 score 값만을 가져와서 set() 함수를 통해 집합을 만든다.

   중복이 제거된 집합을 구할 수 있다.

   결과값: {41.0, 37.2, 37.21, 39.0}

set([score for name, score in marksheet])

3. 2번에서 구한 집합을 다시 list 타입으로 변환한다.

   결과값: [41.0, 37.2, 37.21, 39.0]

list(set([score for name, score in marksheet]))

4. 변경된 리스트를 정렬한다. 

   결과값: [37.2, 37.21, 39.0, 41.0]

sorted(list(set([score for name, score in marksheet])))

5. 정렬된 리스트에서 2번째로 작은 값을 가져온다.

   2번에서 집합으로 변경할 때 중복이 제거되었기 때문에 [1]만 추가하면 2번째로 작은 값을 구할 수 있다.

   결과값: 37.21

sorted(list(set([score for name, score in marksheet])))[1]

6. marksheet 리스트를 정렬한다. 인덱스가 없으므로 첫 번째 인덱스를 기준으로 정렬된다.

   결과값: [['Akriti', 41.0], ['Berry', 37.21], ['Harry', 37.21], ['Harsh', 39.0], ['Tina', 37.2]]

sorted(marksheet)

7. 정렬된 리스트에서 name 값만을 가져온다.

   결과값: ['Akriti', 'Berry', 'Harry', 'Harsh', 'Tina']

[a for a,b in sorted(marksheet)]

8. if b == second_highest 구문이 추가되어 name 값을 가져오는데 score값이 second_highest 값과 동일한 경우에만 name 값을 가져오도록 한다.

   결과값: ['Berry', 'Harry']

[a for a,b in sorted(marksheet) if b == second_highest]

9. 최종적으로 나온 ['Berry', 'Harry'] 결과값을 리스트 형태가 아닌 값으로 출력해야 하므로 join() 함수를 사용해서 출력 형태를 변경한다.

   결과값:

   Berry
   Harry

'\n'.join([a for a,b in sorted(marksheet) if b == second_highest])

 

728x90
LIST
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함