ジェネレータさん

イテレータとジェネレータ。
お気楽 Python プログラミング入門:第4回正規表現とジェネレータ

Python にはイテレータ (iterator) という、コレクションから要素を順番に取り出す機能があります。実をいうと、 for 文で要素を順番に取り出せるのは背後でイテレータが働いているからです。

あんまり意識しないけど、重要なもよう。
特に深入りすることは現時点ではない。
要素がなくなるとnext()は例外を返す。

イテレータはコレクションの要素を順番に取り出すだけですが、ジェネレータ (generator) を使うと値を一つずつ順番に生成することができます。

これ面白そう。

関数 generator() は start から end 未満の数値を step きざみで生成します。同じことは range() でもできますが、リストを生成しないぶんだけ generator() の方が効率的です。簡単な実行例を示します。

って書いてたので、実験。

import time

def generator(start, end, step):
    n = start
    while n < end:
        yield n
        n += step

def main():
    start = time.clock()
    generator(0,100,1)
    print time.clock() - start

    start = time.clock()
    range(100)
    print time.clock() - start

    print

    start = time.clock()
    generator(0,100000,1)
    print time.clock() - start

    start = time.clock()
    range(100000)
    print time.clock() - start


if __name__ == "__main__":
    main()

結果

D:\workspace\Python\3-7>python test.py
1.56388625735e-006
8.67956872829e-006

2.13831370957e-006
0.00288135817507

確かにジェネレータの方が早い。

いつぞやの

スタック使って括弧の対応見るコード。
オブジェクト指向の練習にスタッククラスを作ってみた。
ただそれだけ。

# -*- encoding : utf-8 -*-

class Stack:
    def __init__(self):
        self.element = []
        
    def push(self,x):
        self.element.append(x)

    def pop(self):
        if len(self.element) == 0:
            return False
        else:
            return self.element.pop()

def check():
    stack = Stack()

    f = open("kakko.txt", "r")

    line = 0
    pos = 0

    for lines in f.readlines():
        line += 1
        for ch in lines:
            pos += 1
            if ch != "\n":
                k = kind(ch)
                if k == 1:
                    stack.push(pos)
                    stack.push(line)
                elif k == 2:
                    if len(stack.element) > 0:
                        stack.pop()
                        stack.pop()
                    else:
                        print u"対応する開き括弧がありません"
                        print "Line:%d Position:%d\n" % (line, pos)
        pos = 0
    f.close()

    if len(stack.element) > 0:
        while len(stack.element) > 0:
            print u"対応する閉じ括弧がありません"
            print "Line:%d Position:%d\n" % (stack.pop(), stack.pop())

def kind(ch):
    if ch == "(":
        return 1
    elif ch == ")":
        return 2
    else:
        return 0

def main():
    check()

if __name__ == "__main__":
    main()

結果はもちろんこの前と同じ

D:\workspace\Python\3-7>python check2.py
対応する開き括弧がありません
Line:2 Position:4

対応する開き括弧がありません
Line:3 Position:10

対応する閉じ括弧がありません
Line:5 Position:4

対応する閉じ括弧がありません
Line:4 Position:1

リストをそのまま使っても変わらんな。
無駄にコードが長くなっただけ。
まあ練習ですしね。