다음은 이름과 혈액형으로 구성한 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))
출력 결과
👉 혈액형이 바뀔 때마다 혈액형 그룹이 생성되어 뒤죽박죽이 된다