Pythonでカレンダーを操作:calendar.Calendar.itermonthdays()徹底解説


この関数の詳細

  • 挙動
    • イテレータを反復処理すると、指定された年と月の各日が順番に返されます。
    • 各日の値は、その日がその月の中で何番目の日であるかを表す整数値です。
    • 先頭の日付は常に 1 になります。
    • 末尾の日付は、月の末日の値になります。
    • 閏年には、2 月が 29 日になるため、29 番目の日付も返されます。
  • 戻り値
    指定された年と月の各日のみを含むイテレータ
  • 引数
    • year: 対象となる年の整数値
    • month: 対象となる月の整数値 (1~12)
  • メソッド
    itermonthdays(year, month)
  • クラス
    Calendar
  • モジュール
    calendar


import calendar

# 2024年1月の各日を出力
for day in calendar.Calendar().itermonthdays(2024, 1):
    print(day)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  • カレンダー全体を出力したい場合は、calendar.month() 関数を使用できます。
  • 特定の曜日のみを出力したい場合は、filter() 関数と組み合わせて使用できます。
  • itermonthdays() は、itermonthdates() と似ていますが、曜日情報を含まない点が異なります。


特定の曜日のみを出力する

import calendar

def is_weekday(day):
    return day not in (calendar.SUNDAY, calendar.SATURDAY)

# 2024年1月の平日のみを出力
for day in calendar.Calendar().itermonthdays(2024, 1):
    if is_weekday(day):
        print(day)

出力

1
2
3
4
5
8
9
10
11
12
15
16
17
18
19
22
23
24
25
26
29
30
31

特定の範囲の日付を出力する

import calendar

def is_in_range(day, start_day, end_day):
    return start_day <= day <= end_day

# 2024年1月の10日から20日までの各日を出力
for day in calendar.Calendar().itermonthdays(2024, 1):
    if is_in_range(day, 10, 20):
        print(day)

出力

10
11
12
13
14
15
16
17
18
19
20
import calendar

def generate_calendar(year, month):
    """指定された年と月のカレンダーを生成する"""
    month_days = calendar.Calendar().itermonthdays(year, month)
    first_weekday = calendar.firstweekday()

    # カレンダーの最初の行を作成
    calendar_rows = [[" " for _ in range(first_weekday)]]
    for day in month_days:
        # 1 週間の行を作成
        if len(calendar_rows[-1]) == 7:
            calendar_rows.append([])
        calendar_rows[-1].append(str(day).zfill(2))

    # カレンダー全体を出力
    for row in calendar_rows:
        print(" ".join(row))

# 2024年1月のカレンダーを出力
generate_calendar(2024, 1)

出力

 Mo Tu We Th Fr Sa Su
  1 2 3 4 5 6 7
 8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

これらの例は、calendar.itermonthdays() をさまざまな目的にどのように使用できるかを示すほんの一例です。



代替方法として考えられるもの

    • range() 関数を使用して、1 から月の末日までを表す数値リストを作成します。
    • calendar.monthrange() 関数を使用して、月の開始日と終了日を取得します。
    • リストスライシングを使用して、開始日から終了日までの各日を含む新しいリストを作成します。
import calendar

def iter_monthdays(year, month):
    """指定された年と月の各日を出力するイテレータを返す"""
    start_day, end_day = calendar.monthrange(year, month)
    return range(start_day, end_day + 1)

# 2024年1月の各日を出力
for day in iter_monthdays(2024, 1):
    print(day)

利点

  • 柔軟性が高い
  • シンプルで分かりやすいコード

欠点

  • 閏年の処理がやや煩雑
  1. リスト内包表記

    • リスト内包表記を使用して、1 から月の末日までを表す数値リストを作成します。
    • 各要素に、その日がその月の中で何番目の日であるかを表す整数値を代入します。
def iter_monthdays(year, month):
    """指定された年と月の各日を出力するイテレータを返す"""
    _, end_day = calendar.monthrange(year, month)
    return [day for day in range(1, end_day + 1)]

# 2024年1月の各日を出力
for day in iter_monthdays(2024, 1):
    print(day)

利点

  • コードが簡潔

欠点

  • 読みづらい場合がある
  1. Numpy ライブラリ

    • Numpy ライブラリを使用して、1 から月の末日までを表す数値配列を作成します。
    • reshape() 関数を使用して、配列を 1 次元から 2 次元に変換します。
    • 各要素に、その日がその月の中で何番目の日であるかを表す整数値を代入します。
import numpy as np

def iter_monthdays(year, month):
    """指定された年と月の各日を出力するイテレータを返す"""
    _, end_day = calendar.monthrange(year, month)
    days = np.arange(1, end_day + 1).reshape(-1, 1)
    return days.flatten()

# 2024年1月の各日を出力
for day in iter_monthdays(2024, 1):
    print(day)

利点

  • メモリ効率が良い
  • 高速処理

欠点

  • Numpy ライブラリの知識が必要

どの方法が最適かは、状況によって異なります。

  • 高速処理やメモリ効率を重視する場合は、Numpy ライブラリを使用するのがおすすめです。
  • コードの簡潔さを重視する場合は、リスト内包表記がおすすめです。
  • シンプルで分かりやすいコードが必要な場合は、リストの操作がおすすめです。
  • 上記以外にも、itertools モジュールの product() 関数などを組み合わせて使用する方法もあります。
  • [Itertools: product() - Python 3.11