Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python에서 두 요소 리스트를 공통 값 기준으로 그룹화하는 3가지 방법

각 하위 리스트가 두 개의 요소로 구성된 리스트가 있다고 가정해 보겠습니다. 이때 하위 리스트의 한 요소는 다른 여러 하위 리스트에 걸쳐 공통적으로 나타납니다. 우리가 해야 할 작업은 이 공통 요소를 기준으로 하위 리스트들을 묶어 하나의 최종 리스트를 만드는 것입니다.

예를 들어 첫 번째 요소는 요일(문자열), 두 번째 요소는 숫자인 데이터가 있다면, 같은 숫자를 가진 요일들을 하나의 그룹으로 묶을 수 있습니다. 아래에서 세 가지 방법을 소개합니다.

1. set과 map 활용

주어진 리스트에서 첫 번째 요소는 문자열이고 두 번째 요소는 숫자입니다. 먼저 map과 람다 함수를 이용해 각 하위 리스트의 두 번째 요소만 추출한 뒤 set으로 만들어 고유한 값들의 임시 집합을 생성합니다. 그다음 각 하위 리스트를 이 집합의 요소와 비교하여 조건에 맞는 첫 번째 요소들을 모아 그룹화합니다.

예제 코드

listA = [['Mon', 2], ['Tue', 3], ['Wed', 3],
["Thu", 1], ['Fri', 2], ['Sat', 3],
['Sun', 1]]
# set과 map 활용
temp = set(map(lambda i: i[1], listA))
res = [[j[0] for j in listA if j[1] == i] for i in temp]
# 결과 출력
print("The list with grouped elements is : \n" ,res)

실행 결과

위 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

The list with grouped elements is :
[['Thu', 'Sun'], ['Mon', 'Fri'], ['Tue', 'Wed', 'Sat']]

2. groupby와 itemgetter 활용

itertools.groupby를 사용하기 전에는 반드시 그룹화 기준이 되는 키로 리스트를 정렬해야 합니다. operator.itemgetter 함수로 각 하위 리스트의 두 번째 요소를 기준 키로 가져오고, 정렬 후 groupby를 적용하면 동일한 키를 가진 항목들이 순서대로 묶입니다.

예제 코드

from itertools import groupby
from operator import itemgetter
listA = [['Mon', 2], ['Tue', 3], ['Wed', 3],["Thu", 1], ['Fri', 2], ['Sat', 3],['Sun', 1]]
# groupby 활용
listA.sort(key = itemgetter(1))
groups = groupby(listA, itemgetter(1))
res = [[i[0] for i in val] for (key, val) in groups]
# 결과 출력
print("The list with grouped elements is : \n" ,res)

실행 결과

위 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

The list with grouped elements is :
[['Thu', 'Sun'], ['Mon', 'Fri'], ['Tue', 'Wed', 'Sat']]

3. defaultdict 활용

collections.defaultdict를 사용하면 가장 직관적이고 효율적으로 그룹화할 수 있습니다. 하위 리스트의 두 번째 요소를 딕셔너리의 키로 사용하고, 반복문을 돌며 각 키에 해당하는 값 리스트에 첫 번째 요소를 추가(append)하는 방식입니다. 키가 존재하지 않아도 자동으로 빈 리스트가 생성되므로 별도의 초기화 코드가 필요 없다는 장점이 있습니다.

예제 코드

import collections
listA = [['Mon', 2], ['Tue', 3], ['Wed', 3],["Thu", 1], ['Fri', 2], ['Sat', 3],['Sun', 1]]
# defaultdict 활용
res = collections.defaultdict(list)
for val in listA:
    res[val[1]].append(val[0])
# 결과 출력
print("The list with grouped elements is : \n" ,res)

실행 결과

위 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

The list with grouped elements is :
defaultdict(<class 'list'>, {2: ['Mon', 'Fri'], 3: ['Tue', 'Wed', 'Sat'], 1: ['Thu', 'Sun']})

마무리

세 가지 방법 모두 동일한 그룹화 결과를 제공하지만 상황에 따라 선택 기준이 다릅니다. 간단한 일회성 처리라면 set + map, 정렬된 순서가 필요하다면 groupby + itemgetter, 성능과 가독성을 모두 고려한다면 defaultdict 방식을 권장합니다. 특히 대량의 데이터를 다룰 때는 O(n) 시간 복잡도를 가지는 defaultdict 방식이 가장 효율적입니다.