개요

python 자료 처리에 핵심적인 부분을 다시 정리한다.

  • List 자료형
  • *csv 파일 불러오기
  • for / if
  • 교환 로직

기본기가 가장 중요하다.


데이터 조작 전 처리

python에서 읽어 들이는 기본 인코딩 형식은 utf-8이다.

이전에 했던 실습파일을 그대로 사용했다.

# *csv 읽어들이기

path = '파일경로'

# open()함수를 사용하여 파일을(path: 파일경로) 읽기전용('r')으로 읽기
file = open(path, 'r')

# readlines()함수를 사용하여 리스트에 문자열단위로 받기
lines = file.readlines()

# 작업이 완료된 후 파일을 반드시 닫아준다
file.close()

print(lines)
>>
['990001,addx, 17, 29, 16, 49, 43,154,C,A,C\n',
'990002,stch, 30,  9, 48, 25, 81,193,C,A,A\n',
'990003,gali, 93, 60,  6, 84, 36,279,A,C,A\n',
'990004,miat, 73, 22, 48, 24, 72,239,B,C,C\n',
'990005,oran, 33, 38, 59, 58, 28,216,C,B,A\n',
'990006,sj24, 27, 65, 54, 77, 33,256,B,A,A\n',
'990007,kor2, 33, 85, 98, 60, 66,342,A,B,A\n',
'990008,vsky, 41,  5, 99, 14, 67,226,C,A,C\n',
'990009,kimd, 74,  4,  1, 33, 53,165,B,C,A\n',
'990010,blue, 55, 84, 50, 89, 37,315,A,B,A\n',
'990011,moja, 43, 69, 68, 23, 92,295,B,A,C\n',
'990012,bleu, 15,  5, 19, 97, 88,224,B,C,C\n',
...
  • .readlines()는 *csv 파일의 한 줄 한 줄을 하나의 요소로 만들어 리스트 형태로 받아준다
  • ''로 묶인 하나의 문자열이 학생 한 명의 정보를 의미한다
  • 학번∙이름∙국어점수∙영어점수∙수학점수∙과학점수∙국사점수∙담임코드∙성취도∙지역코드

학생의 세부 정보에도 인덱스로 접근할 수 있도록 중첩 리스트를 만들어줄 것이다.

# 중첩 리스트로 만들 리스트 선언
student_info = []

# 문자열 하나씩을 순회한다
for i in lines:
	# ' '안에 콤마를 기준으로 모두 끊어서 temp에 할당한다
    # split()메서드로 문자열을 끊어 리스트로 만든다
    temp = i[:-1].split(',')
    # 점수 부분은 숫자로 처리해야 한다
    # 담임코드, 성취도, 지역코드는 숫자로 바꿀 필요가 없다
    for i in range(len(temp)-3):
		# 이름은 숫자로 바꿀 필요가 없다
		if i == 1:
            continue
        if type(temp[i]) != int:
        	# 점수는 따옴표로 묶여있다
            # 정수형으로 바꿔준다
            temp[i] = int(temp[i])
    # 리스트에 넣어준다
    student_info.append(temp)
  • split(문자열을 끊을 기준)
    • 파라미터를 기준으로 문자열을 끊어준다
    • 문자열의 조각조각을 리스트의 요소로 삼아 해당 리스트를 반환한다
    • 조각조각나서 리스트로 들어가는 요소들의 자료형도 문자열이다

종합해보자면, SPLIT(   ) 메서드는 문자열을 분해하여 리스트로 만들어주는 메서드이다

아래에 split(',')를 사용한다고 하면

'990001,addx, 17, 29, 16, 49, 43,154,C,A,C\n'
  • 문자열은
    990001 / addx / 17 / 29 / 16 / 49 / 43 / 154 / C / A / C 으로 나뉘고
    각각의 자료형은 문자열이 된다
    이들이 하나의 리스트의 요소가 되어 반환된다
>> ['990001', 'addx', '17', '29', '16', '49', '43', '154', 'C', 'A', 'C']

이렇게 하면 한 학생의 모든 정보에 인덱스를 통해 접근할 수 있게 된다.


Q. 다음의 조건을 만족하는 함수를 정의하시오

  1. 매개변수
    1-1. 식별코드를 받아야 한다(담임코드 / 성취도 / 지역코드)
    1-2. 식별코드의 내용을 받아야 한다(A / B / C)
    1-3. 과목명을 받아야 한다

  2. 반환값
    식별코드와 식별코드값을 사용하여 특정과목의 평균점수를 반환해야 한다

A. 반복문과 LIST 요소 접근 연산자를 사용하여 값을 구한다

  • 먼저 파라미터로 받을 STR형 과목명과 식별코드를 매핑할 dictionary를 생성해준다
# 맵핑을 위한 dict 생성
prop_keys = {
			"국어":2, "영어":3, "수학":4, "과학":5, "국사":6, 
            "총점":7, 
            "담임":{"담임":8, "A":5, "B":15, "C":20}, 
            "지역":{"index":10, "A":5, "B":10, "C":15}
            }

하드코딩을 최대한 지양하고 추후 수정을 조금이라도 더 간편하게 하기 위해서이다.
간단한 코드에 이런 작업이 필요할까 의문이 들 수 있지만 습관을 들여야 한다.

def get_avg(code, code_value, subject):
    # 필요한 변수들을 미리 준비해둔다
    avg = 0
    count = 0
    summary = 0
    
    # 학생 한명한명의 정보를 순회할 것이다
    for data in student_info:
    	# 평균 계산을 위해 수를 센다
        count += 1
        
        # 매개변수로 받은 subject(과목명)을 매핑 dictionary를 통해 인덱스로 변환한다
        # 최종적으로 data[과목의 인덱스]가 되어 값을 얻을 수 있다
        summary += data[prop_keys[subject]]
        summary += prop_keys[code][code_value]
    
    avg = summary / count

	return avg

# 함수 호출
A_2 = get_avg("담임","A","국어")
B_2 = get_avg("담임","B","국어")
C_2 = get_avg("담임","C","국어")

print(A_2)
print(B_2)
print(C_2)
>>
75.70480081716036
85.70480081716036
90.70480081716036

Q. 다음의 조건을 만족하는 함수를 정의하시오

  1. 매개변수
    1-1. 과목명을 받아야 한다
    1-2. 정렬 기준은 기본값을 정하여 기본 매개변수로 정해야 한다
    1-3. 시작 등수는 기본값을 정하여 기본 매개변수로 정해야 한다
    1-4. 몇 등까지 출력할 것인지를 기본 매개변수로 정해야 한다

  2. 반환값
    2-1. 사용자가 원하는 매개변수를 넣었을 때 원하는 정보가 중첩 리스트로 반환되어야 한다
    2-2. 이 때 리스트 내의 리스트는 학생 1명의 정보를 담고 있어야 한다

    A. 정렬 기준에 대해서는 교환 로직을 사용한다 / 요소 접근에 주의하고 인덱스 값에 집중한다

def get_select_with_sorting(target, sort=1, start=1, count=1):

    result = []
    count = start-1+count
    
    # 정렬 기준부터 정한다
    if sort == 1 :
    	# 교환 로직을 적용하기 위해 첫 인덱스를 고정하고
        for i in range(len(student_info)-1) :
        	# 나머지 인덱스와 비교한다
            for j in range(i+1, len(student_info)-1) :
            	# 비교 결과과 '참'이라면
                if student_info[i][prop_keys[target]] < student_info[j][prop_keys[target]] :
                    # 교환을 실행한다
                    temp              = student_info[i]
                    student_info[i]   = student_info[j]
                    student_info[j] = temp
                    pass
        # 교환이 완료된 리스트를 리턴에 사용할 리스트에 할당한다
        result = student_info[start-1:count]
        return result

    if sort == 0 :
        for i in range(len(student_info)-1) : 
            for j in range(i+1, len(student_info)-1) :
                if student_info[i][prop_keys[target]] > student_info[j][prop_keys[target]] :
                    temp              = student_info[i]
                    student_info[i]   = student_info[j]
                    student_info[j] = temp
                    pass
        
        result = student_info[start-1:count]
        return result
  • 코드는 길어보이나 어려운 문법은 하나도 들어있지 않다
  • 매핑과 요소 접근에 얼마나 집중하느냐가 관건이었다

0개의 댓글