[1,2,3,4,10,11,12,13,20,21,22,23,24,25] 와 같은 리스트가 있다고 가정합시다.
보면 1, 2, 3, 4 순서대로 가다가 어느 순간 다른 숫자가 튀어나오고 또 어느 순간 연속되지 않은 숫자가 나타납니다.
이 리스트를 연속되는 숫자들로만 새롭게 구성해서 나타내고 싶을 때 사용하는 방법입니다.
리스트 내에서 연속되는 숫자의 배열(시퀀스)을 찾기 위해서는, 리스트를 순회하면서 각 숫자가 이전 숫자와 연속적인지를 확인하는 방법을 사용할 수 있습니다.
연속적이지 않은 숫자가 나타나면, 새로운 연속적인 시퀀스의 시작으로 간주할 수 있습니다.
이런 방식으로 리스트를 분할하여 각 연속적인 숫자 시퀀스를 구분할 수 있습니다.
from itertools import groupby
# 주어진 리스트
numbers = [1,2,3,4,10,11,12,13,20,21,22,23,24,25]
# 연속되는 숫자의 배열을 찾기 위한 함수
def find_continuous_sequences(numbers):
# 숫자와 그 이전 숫자의 차이를 기준으로 그룹화
continuous = []
for k, g in groupby(enumerate(numbers), lambda ix : ix[0] - ix[1]):
continuous.append(list(map(lambda x: x[1], g)))
return continuous
# 연속되는 숫자의 배열 찾기
sequences = find_continuous_sequences(numbers)
# 결과 출력
print(sequences)
코드로 구성하자면 위와 같습니다.
결과는 아래와 같이 나타나게 됩니다.
[1, 2, 3, 4]
[10, 11, 12, 13]
[20, 21, 22, 23, 24, 25]
itertools.groupby 함수는 연속된 요소들을 그룹화하여, 각 그룹에 대한 반복자(iterator)를 생성합니다.
이 함수는 주어진 시퀀스를 순회하며, 특정 기준(키 함수에서 반환된 값)에 따라 연속된 요소들을 그룹으로 묶습니다.
여기서 중요한 점은 groupby가 시퀀스를 정렬된 상태로 가정하고, 오직 연속된 요소들만을 그룹화한다는 것입니다.
groupby 원리
groupby 함수를 사용할 때, 두 가지 중요한 요소를 제공해야 합니다.
반복 가능 객체(iterable): 분석하고자 하는 데이터 시퀀스입니다.
키 함수(key function): 각 요소를 분류하는 기준이 되는 값을 반환하는 함수입니다. 이 함수는 시퀀스의 각 요소에 적용되며, 반환된 값에 따라 그룹화가 이루어집니다.
예시 코드 해설
예시 코드에서는 enumerate(numbers)를 사용하여 각 숫자의 인덱스와 값을 튜플로 만듭니다.
이 튜플의 형태는 (index, value)가 됩니다. 그런 다음, lambda ix : ix[0] – ix[1] 키 함수를 통해 각 요소의 인덱스와 그 값의 차이를 계산합니다.
이 차이를 기준으로 groupby가 그룹화를 수행합니다.
이 방식의 핵심은 인덱스와 값의 차이가 연속된 숫자들 사이에서는 일정하다는 점을 이용하는 것입니다.
예를 들어, 숫자 1, 2, 3은 인덱스가 각각 0, 1, 2이므로, 각각의 (index – value)는 -1이 됩니다.
따라서 이 숫자들은 같은 그룹으로 묶입니다.
코드 실행 과정
인덱스 부여: (0, 1), (1, 2), (2, 3), …와 같이 각 숫자에 인덱스가 부여됩니다.
차이 계산: 인덱스와 값의 차이를 계산합니다. 연속된 숫자들은 같은 차이값을 가집니다.
그룹화: 차이값이 같은 요소들을 그룹으로 묶습니다.
그룹 추출: 각 그룹에서 숫자만을 추출하여 새로운 리스트를 생성합니다.
이 방법을 통해, 주어진 리스트에서 연속된 숫자 시퀀스를 효과적으로 찾아낼 수 있습니다.
groupby 함수는 연속된 요소들을 기준(여기서는 인덱스와 값의 차이)에 따라 그룹화하여, 이러한 시퀀스를 쉽게 식별할 수 있게 해줍니다. 각 그룹은 연속된 숫자의 시퀀스를 나타내며, 최종적으로 이 시퀀스들의 리스트를 반환합니다.
굳이 1부터 차근차근 시작을 하지 않더라도 가능합니다.
예를 들어 아래와 같은 리스트를 적용하더라도 각 인덱스 값의 차이가 1로 연속되는 숫자를 리스트로 묶어 반환이 가능합니다.
[19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 39, 40, 41]