中学理科1630641 views
教育149510 views
MathPython497343 views
英語613639 views
中学社会668760 views
雑学1473612 views
高校生物551766 views
数学講師2886227 views
高校化学2924392 views
りんご209490 views
Help
Tools
NewsSpreadsheetCalendarSlidesTier ListPen ToolIllustrationCrayonPixel ArtASCII ArtPerspectiveEndless StairsGraphMind MapER DiagramFamily TreeMemeCurved TextImage EditorMosaicRetro FilterPencil SketchOCR/HighlighterMakeup EditorFaviconVideo TrimmerScrolling VideoVideo TitleColor PickerColor ExtractorBonfireFireworksWater RippleWater SplashBreaking GlassWood GrainMarble TextureCSS ButtonIcon MakerBar ChartGrouped Bar ChartStacked Bar ChartPie ChartLine ChartArea ChartStacked Area ChartScatter Plot3D Bar Chart3D Pie ChartBar Chart RaceBubble ChartPopulation PyramidPictogramEarningsCandlestick ChartInvestment RiskMortgage SimulatorCalculatorMatrix CalculatorFunction GraphPolynomial ExpansionVenn DiagramField VisualizerRubik's Cube Group TheoryTraveling SalesmanVoronoi and DelaunayFractalColumn ArithmeticDraw Math FiguresArithmetic AnimationArithmetic Word ProblemsCounting with Tree DiagramsCube NetsCross SectionsMotion PathMechanicsWavesLight and LensesThermodynamicsHow Semiconductors WorkMolecular StructuresAtomic OrbitalsElectrochemical CellsChemical EquilibriumCrystal LatticesBuffer pHComplex IonsDNA Double HelixCell DivisionMembrane ChannelsNerve ImpulseRock ClassificationWeatherConstellationsSolar and Lunar Eclipses3D ModelingFloor PlanSeismic StructuresIntersection TurnMaglevCooking AnimationOrigamiLive Viewer CountGeoJSON MapRailway MapPopulation MapCrime MapLand Price MapSchool MapShrine and Castle MapHouse of Representatives MapWord MapSolitaireReversiHakoiri MusumeChessHamburgerRippleSlide Puzzle MakerNeon PinballNovel MakerJapanese Typing PracticePiano Score EditorMusic Theory

English

Python でクラスを使ったカスタムイテレータを作る

クラスを使ってカスタムイテレータを作ると、複雑な状態管理やカスタムロジックを持つイテレータを実装できます。ここでは実践的な例をいくつか紹介します。

範囲イテレータ

Python の range() のような機能を持つイテレータを作ってみましょう。

class MyRange:
    def __init__(self, start, stop, step=1):
        self.start = start
        self.stop = stop
        self.step = step
    
    def __iter__(self):
        current = self.start
        while current < self.stop:
            yield current
            current += self.step

for n in MyRange(0, 10, 2):
    print(n, end=" ")
# 0 2 4 6 8

逆順イテレータ

リストを逆順でイテレートするクラスです。

class Reversed:
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index -= 1
        return self.data[self.index]

for char in Reversed("hello"):
    print(char, end="")
# olleh

サイクルイテレータ

要素を無限に繰り返すイテレータです。

class Cycle:
    def __init__(self, iterable):
        self.items = list(iterable)
        self.index = 0
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if not self.items:
            raise StopIteration
        item = self.items[self.index]
        self.index = (self.index + 1) % len(self.items)
        return item

colors = Cycle(["red", "green", "blue"])
for i, color in enumerate(colors):
    if i >= 7:
        break
    print(color, end=" ")
# red green blue red green blue red

ファイル行イテレータ

ファイルを特定の条件でフィルタリングしながら読み込むイテレータです。

class NonEmptyLines:
    def __init__(self, filename):
        self.filename = filename
        self.file = None
    
    def __iter__(self):
        self.file = open(self.filename, 'r')
        return self
    
    def __next__(self):
        while True:
            line = self.file.readline()
            if not line:
                self.file.close()
                raise StopIteration
            line = line.strip()
            if line:  # 空行をスキップ
                return line

# 使用例
# for line in NonEmptyLines("data.txt"):
#     print(line)

ペアイテレータ

隣り合う要素をペアで返すイテレータです。

class Pairwise:
    def __init__(self, iterable):
        self.iterator = iter(iterable)
        self.prev = None
        self.started = False
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if not self.started:
            self.prev = next(self.iterator)
            self.started = True
        
        current = next(self.iterator)
        result = (self.prev, current)
        self.prev = current
        return result

numbers = [1, 2, 3, 4, 5]
for pair in Pairwise(numbers):
    print(pair)
# (1, 2)
# (2, 3)
# (3, 4)
# (4, 5)

設計のポイント

状態管理

インスタンス変数で現在位置や状態を管理する。__next__() で状態を更新する。

再利用性

同じオブジェクトを複数回イテレートしたい場合は、__iter__() で新しいイテレータを返す設計にする。

クラスベースのイテレータは柔軟性が高いですが、シンプルなケースではジェネレータ関数を使う方が簡潔です。