파이썬에서 중복일정 처리하기

조회수 498회

일정 목록을 반복문으로 처리하여 텍스트로 쓰는 스크립트를 만들고 있습니다.

중복되는 일정을 묶어내어 표시하는 기능을 구현하고 있는데, 마음대로 구현되지 않습니다.

원래대로라면 최종 출력값(코드에서 body)이 이렇게 나와야 합니다:

2019-01-01(화):
신정
2019-01-05(일)~2019-02-03(일):
겨울방학
2019-02-04(월):
겨울방학
설연휴
2019-02-05(화):
겨울방학
설날
2019-02-06(수):
겨울방학
설연휴
2019-02-07(금)~2019-02-28(목):
겨울방학

그런데 코드를 실행해 보면 이렇게 나옵니다:

2019-01-01(화):
신정
2019-01-05(토):
겨울방학
2019-01-06(일)~2019-02-03(일):
겨울방학
2019-02-04(월):
겨울방학
설연휴
2019-02-05(화):
겨울방학
설날
2019-02-06(수):
겨울방학
설연휴
2019-02-07(목):
겨울방학
2019-02-08(금)~2019-02-28(목):
겨울방학

결과값애서 1월 5일부터 2월 3일까지 겹치는 일정임에도 불구하고 1월 5일이 따로 나와 있습니다.

prev_schdl = None
schdl_start_date = None
schdl_end_date = None

for i in schdls:
    date = datetime.date(int(i[0]), int(i[1]), int(i[2]))  # 년, 월, 일
    prsnt_schdl = pstpr(i[3])  # 일정

    if prsnt_schdl:
        if not schdl_start_date:
            schdl_start_date = date
            schdl_end_date = date

        if prsnt_schdl == prev_schdl:  # 이전 일정과 같을 경우, 종료일 갱신
            schdl_end_date = date
        elif schdl_start_date:
            if not schdl_start_date == schdl_end_date:  # 하루짜리 일정이 아닐 경우
                body = "%s%s(%s)~%s(%s):\n%s\n" % (
                    body, schdl_start_date, wday(schdl_start_date), schdl_end_date,
                    wday(schdl_end_date), prev_schdl)  # YYYY-MM-DD(Weekday)
            body = "%s%s(%s):\n%s\n" % (body, date, wday(date), prsnt_schdl)  # YYYY-MM-DD(Weekday)
            # 변수 초기화
            schdl_start_date = None
            schdl_end_date = None

        prev_schdl = prsnt_schdl  # 이전 일정 저장

if prev_schdl:  # 해당월의 마지막 일정일 경우에도 기록
    body = "%s%s(%s)~%s(%s):\n%s\n" % (body, schdl_start_date, wday(schdl_start_date), schdl_end_date,
                                       wday(schdl_end_date), prev_schdl)  # YYYY-MM-DD(Weekday)

위 코드에서 schdls는 리스트이고,

  [(2019, 1, 1, '신정'), (2019, 1, 2, '일정이 없습니다.'), (2019, 1, 3, '일정이 없습니다.'), (2019, 1, 4, '일정이 없습니다.'), (2019, 1, 5, '겨울방학\n토요휴업일'), (2019, 1, 6, '겨울방학'), (2019, 1, 7, '겨울방학'), (2019, 1, 8, '겨울방학'), (2019, 1, 9, '겨울방학'), (2019, 1, 10, '겨울방학'), (2019, 1, 11, '겨울방학'), (2019, 1, 12, '겨울방학\n토요휴업일'), (2019, 1, 13, '겨울방학'), (2019, 1, 14, '겨울방학'), (2019, 1, 15, '겨울방학'), (2019, 1, 16, '겨울방학'), (2019, 1, 17, '겨울방학'), (2019, 1, 18, '겨울방학'), (2019, 1, 19, '겨울방학\n토요휴업일'), (2019, 1, 20, '겨울방학'), (2019, 1, 21, '겨울방학'), (2019, 1, 22, '겨울방학'), (2019, 1, 23, '겨울방학'), (2019, 1, 24, '겨울방학'), (2019, 1, 25, '겨울방학'), (2019, 1, 26, '겨울방학\n토요휴업일'), (2019, 1, 27, '겨울방학'), (2019, 1, 28, '겨울방학'), (2019, 1, 29, '겨울방학'), (2019, 1, 30, '겨울방학'), (2019, 1, 31, '겨울방학'), (2019, 2, 1, '겨울방학'), (2019, 2, 2, '겨울방학\n토요휴업일'), (2019, 2, 3, '겨울방학'), (2019, 2, 4, '겨울방학\n설연휴'), (2019, 2, 5, '겨울방학\n설날'), (2019, 2, 6, '겨울방학\n설연휴'), (2019, 2, 7, '겨울방학'), (2019, 2, 8, '겨울방학'), (2019, 2, 9, '겨울방학\n토요휴업일'), (2019, 2, 10, '겨울방학'), (2019, 2, 11, '겨울방학'), (2019, 2, 12, '겨울방학'), (2019, 2, 13, '겨울방학'), (2019, 2, 14, '겨울방학'), (2019, 2, 15, '겨울방학'), (2019, 2, 16, '겨울방학\n토요휴업일'), (2019, 2, 17, '겨울방학'), (2019, 2, 18, '겨울방학'), (2019, 2, 19, '겨울방학'), (2019, 2, 20, '겨울방학'), (2019, 2, 21, '겨울방학'), (2019, 2, 22, '겨울방학'), (2019, 2, 23, '겨울방학\n토요휴업일'), (2019, 2, 24, '겨울방학'), (2019, 2, 25, '겨울방학'), (2019, 2, 26, '겨울방학'), (2019, 2, 27, '겨울방학'), (2019, 2, 28, '겨울방학')]

이렇게 값이 들어 있습니다.

pstpr는 토요휴업일 같은 불필요한 정보를 제거해주는 함수입니다.

어떻게 하면 좋을까요?

수정: 실제로 실행 가능한 코드 첨부합니다.

import datetime
prev_schdl = None
schdl_start_date = None
schdl_end_date = None
schdls = [(2019, 1, 1, '신정'), (2019, 1, 2, '일정이 없습니다.'), (2019, 1, 3, '일정이 없습니다.'), (2019, 1, 4, '일정이 없습니다.'), (2019, 1, 5, '겨울방학'), (2019, 1, 6, '겨울방학'), (2019, 1, 7, '겨울방학'), (2019, 1, 8, '겨울방학'), (2019, 1, 9, '겨울방학'), (2019, 1, 10, '겨울방학'), (2019, 1, 11, '겨울방학'), (2019, 1, 12, '겨울방학'), (2019, 1, 13, '겨울방학'), (2019, 1, 14, '겨울방학'), (2019, 1, 15, '겨울방학'), (2019, 1, 16, '겨울방학'), (2019, 1, 17, '겨울방학'), (2019, 1, 18, '겨울방학'), (2019, 1, 19, '겨울방학'), (2019, 1, 20, '겨울방학'), (2019, 1, 21, '겨울방학'), (2019, 1, 22, '겨울방학'), (2019, 1, 23, '겨울방학'), (2019, 1, 24, '겨울방학'), (2019, 1, 25, '겨울방학'), (2019, 1, 26, '겨울방학'), (2019, 1, 27, '겨울방학'), (2019, 1, 28, '겨울방학'), (2019, 1, 29, '겨울방학'), (2019, 1, 30, '겨울방학'), (2019, 1, 31, '겨울방학'), (2019, 2, 1, '겨울방학'), (2019, 2, 2, '겨울방학'), (2019, 2, 3, '겨울방학'), (2019, 2, 4, '겨울방학\n설연휴'), (2019, 2, 5, '겨울방학\n설날'), (2019, 2, 6, '겨울방학\n설연휴'), (2019, 2, 7, '겨울방학'), (2019, 2, 8, '겨울방학'), (2019, 2, 9, '겨울방학'), (2019, 2, 10, '겨울방학'), (2019, 2, 11, '겨울방학'), (2019, 2, 12, '겨울방학'), (2019, 2, 13, '겨울방학'), (2019, 2, 14, '겨울방학'), (2019, 2, 15, '겨울방학'), (2019, 2, 16, '겨울방학'), (2019, 2, 17, '겨울방학'), (2019, 2, 18, '겨울방학'), (2019, 2, 19, '겨울방학'), (2019, 2, 20, '겨울방학'), (2019, 2, 21, '겨울방학'), (2019, 2, 22, '겨울방학'), (2019, 2, 23, '겨울방학'), (2019, 2, 24, '겨울방학'), (2019, 2, 25, '겨울방학'), (2019, 2, 26, '겨울방학'), (2019, 2, 27, '겨울방학'), (2019, 2, 28, '겨울방학')]
body = str()

for i in schdls:
    date = datetime.date(int(i[0]), int(i[1]), int(i[2]))  # 년, 월, 일
    prsnt_schdl = i[3]  # 일정

    if prsnt_schdl:
        if not schdl_start_date:
            schdl_start_date = date
            schdl_end_date = date

        if prsnt_schdl == prev_schdl:  # 이전 일정과 같을 경우, 종료일 갱신
            schdl_end_date = date
        elif schdl_start_date:
            if not schdl_start_date == schdl_end_date:  # 하루짜리 일정이 아닐 경우
                body = "%s%s(%s)~%s(%s):\n%s\n" % (
                    body, schdl_start_date, "요일", schdl_end_date,
                    "요일", prev_schdl)  # YYYY-MM-DD(Weekday)
            body = "%s%s(%s):\n%s\n" % (body, date, "요일", prsnt_schdl)  # YYYY-MM-DD(Weekday)
            # 변수 초기화
            schdl_start_date = None
            schdl_end_date = None

        prev_schdl = prsnt_schdl  # 이전 일정 저장

if prev_schdl:  # 해당월의 마지막 일정일 경우에도 기록
    body = "%s%s(%s)~%s(%s):\n%s\n" % (body, schdl_start_date, "요일", schdl_end_date,
                                       "요일", prev_schdl)  # YYYY-MM-DD(Weekday)

print(body)
  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 자문자답 죄송합니다.

    from itertools import groupby
    
    schdls = [(2019, 1, 1, 'aa'), (2019, 1, 5, 'vacation'), (2019, 1, 6, 'vacation'), (2019, 1, 7, 'vacation'), (2019, 1, 8, 'vacation'), (2019, 1, 9, 'vacation'), (2019, 1, 10, 'vacation'), (2019, 1, 11, 'vacation'), (2019, 1, 12, 'vacation'), (2019, 1, 13, 'vacation'), (2019, 1, 14, 'vacation'), (2019, 1, 15, 'vacation'), (2019, 1, 16, 'vacation'), (2019, 1, 17, 'vacation'), (2019, 1, 18, 'vacation'), (2019, 1, 19, 'vacation'), (2019, 1, 20, 'vacation'), (2019, 1, 21, 'vacation'), (2019, 1, 22, 'vacation'), (2019, 1, 23, 'vacation'), (2019, 1, 24, 'vacation'), (2019, 1, 25, 'vacation'), (2019, 1, 26, 'vacation'), (2019, 1, 27, 'vacation'), (2019, 1, 28, 'vacation'), (2019, 1, 29, 'vacation'), (2019, 1, 30, 'vacation'), (2019, 1, 31, 'vacation'), (2019, 2, 1, 'vacation'), (2019, 2, 2, 'vacation'), (2019, 2, 3, 'vacation'), (2019, 2, 4, 'vacation\nbb'), (2019, 2, 5, 'vacation\naa'), (2019, 2, 6, 'vacation\nbb'), (2019, 2, 7, 'vacation'), (2019, 2, 8, 'vacation'), (2019, 2, 9, 'vacation'), (2019, 2, 10, 'vacation'), (2019, 2, 11, 'vacation'), (2019, 2, 12, 'vacation'), (2019, 2, 13, 'vacation'), (2019, 2, 14, 'vacation'), (2019, 2, 15, 'vacation'), (2019, 2, 16, 'vacation'), (2019, 2, 17, 'vacation'), (2019, 2, 18, 'vacation'), (2019, 2, 19, 'vacation'), (2019, 2, 20, 'vacation'), (2019, 2, 21, 'vacation'), (2019, 2, 22, 'vacation'), (2019, 2, 23, 'vacation'), (2019, 2, 24, 'vacation'), (2019, 2, 25, 'vacation'), (2019, 2, 26, 'vacation'), (2019, 2, 27, 'vacation'), (2019, 2, 28, 'vacation')]
    
    for v, g in groupby(schdls, lambda k: k[3]):
        l = [*g]
        if l[0] != l[-1]:
            print('{}-{:02d}-{:02d}(요일)~{}-{:02d}-{:02d}(요일):'.format(*l[0][:3], *l[-1][:3]))
        else:
            print('{}-{:02d}-{:02d}(요일):'.format(*l[0][:3]))
    
        print(v)
    

    itertools.groupby를 이용하면 쉽게 할 수 있었습니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)