키값으로 데이터 묶기

·2022년 11월 21일
0

TIL

목록 보기
36/46

🔸 문제

다음은 이름과 혈액형으로 구성한 8명의 데이터이다

data = [
    {'name': '이민서', 'blood': 'O'},
    {'name': '이영순', 'blood': 'B'},
    {'name': '이상호', 'blood': 'AB'},
    {'name': '김지민', 'blood': 'B'},
    {'name': '최상현', 'blood': 'AB'},
    {'name': '김지아', 'blood': 'A'},
    {'name': '손우진', 'blood': 'A'},
    {'name': '박은주', 'blood': 'A'}
]

이 데이터를 다음처럼 혈액형별로 분류하여 표시하려면 어떻게 해야 할까?

data = {
    'A': [{'name': '김지아', 'blood': 'A'}, {'name': '손우진', 'blood': 'A'}, {'name': '박은주', 'blood': 'A'}], 
    'AB': [{'name': '이상호', 'blood': 'AB'}, {'name': '최상현', 'blood': 'AB'}], 
    'B': [{'name': '이영순', 'blood': 'B'}, {'name': '김지민', 'blood': 'B'}], 
    'O': [{'name': '이민서', 'blood': 'O'}]
}

⌨ 풀이

파이썬 라이브러리 중 itertools.groupby(iterable, key=None)은 반복 가능한 객체를 키값으로 분류하고 그 결과를 반환하는 함수이다
itertools.groupby() 함수를 사용하면 혈액형별로 묶어 데이터를 분류할 수 있다.

함수를 사용하기 전에 분류 기준인 혈액형 순으로 정렬해야 한다

import operator
import pprint

data = [
    {'name': '이민서', 'blood': 'O'},
    {'name': '이영순', 'blood': 'B'},
    {'name': '이상호', 'blood': 'AB'},
    {'name': '김지민', 'blood': 'B'},
    {'name': '최상현', 'blood': 'AB'},
    {'name': '김지아', 'blood': 'A'},
    {'name': '손우진', 'blood': 'A'},
    {'name': '박은주', 'blood': 'A'}
]

data = sorted(data, key=operator.itemgetter('blood')) #혈액형 'blood'
pprint.pprint(data)

🗒 itertools.groupby() 역시 데이터를 혈액형별로 나누어야 하므로 키 항목을 key=operator.itemgetter('blood')와 같이 사용한다. itertools.groupby()는 (분류 기준, 분류 기준으로 묶은 데이터)와 같은 튜플 형식의 이터레이터를 반환한다. 따라서 문제에서 요구하는 결과를 만들기 위해 grouped_data를 아래와 같이 변환해야 한다

import operator
import pprint
import itertools

data = [
    {'name': '이민서', 'blood': 'O'},
    {'name': '이영순', 'blood': 'B'},
    {'name': '이상호', 'blood': 'AB'},
    {'name': '김지민', 'blood': 'B'},
    {'name': '최상현', 'blood': 'AB'},
    {'name': '김지아', 'blood': 'A'},
    {'name': '손우진', 'blood': 'A'},
    {'name': '박은주', 'blood': 'A'}
]

data = sorted(data, key=operator.itemgetter('blood')) #groupby 전 분류 기준으로 정렬
#pprint.pprint(data)
grouped_data = itertools.groupby(data, key=operator.itemgetter('blood'))

result = {}
for key, group_data in grouped_data:
    result[key] = list(group_data) #group_data가 이터레이터이므로 리스트로 변경 

pprint.pprint(result)

출력 결과

정렬하지 않고 groupby()만 적용하면 어떻게 될까?

예)

import itertools
import operator

data = [
    {'name': '이민서', 'blood': 'O'},
    {'name': '이영순', 'blood': 'B'},
    {'name': '이상호', 'blood': 'AB'},
    {'name': '김지민', 'blood': 'B'},
    {'name': '최상현', 'blood': 'AB'},
    {'name': '김지아', 'blood': 'A'},
    {'name': '손우진', 'blood': 'A'},
    {'name': '박은주', 'blood': 'A'}
]

grouped_data = itertools.groupby(data, key=operator.itemgetter('blood'))

result = {}
for key, group_data in grouped_data:
    print(key, list(group_data))

출력 결과

👉 혈액형이 바뀔 때마다 혈액형 그룹이 생성되어 뒤죽박죽이 된다

0개의 댓글