「Python でリストに対する再帰的な関数の適用」では、ネストしたリストに対して、リストのまま関数を適用した。今回はネストしたリストから Composite パターンとなるようにオブジェクトを生成してみる。 Composite にしておけば、後々の操作がしやすくなるかな。
Composite パターン
リストを、オブジェクトを使って次のような構造へ変換する。とりあえず、リスト → オブジェクトへの変換だけなので、要素に相当するクラスは作らない。リストを表わす List クラス、値を表わす Value クラスのみを作成。要素クラスは、List, Value に共通の操作が必要になったときに作成することに。
まずは、List と Value クラス。
class List: BRACKETS = "<>" def __init__(self): self.elems = [] def add(self, elem): self.elems.append(elem); return self def __str__(self): return List.BRACKETS[0] + \ ",".join(str(e) for e in self.elems) + \ List.BRACKETS[1] def __iter__(self): return iter(self.elems) class Value: def __init__(self, val): self.val = val def __str__(self): return str(self.val)
( cf. Python のイテレータ, Python のイテレータ (3) )
Composite を生成する関数
リストからオブジェクトを生成する関数は、前回の再帰的な関数を真似る。
- 渡されたリストがリストであれば、要素に対して再帰的に生成関数を適用する。
- 値であれば、 Value クラスを作成。
def createList(L): if isinstance(L, list): newList = List() for e in L: newList.add(createList(e)) return newList else: return Value(L)
List クラスに要素を追加するメソッドは、最後に自身を返すようにしているので、reduce で書換えることができる。
def createList(L): if isinstance(L, list): return reduce(lambda a,b: a.add(createList(b)), L, List()) else: return Value(L) print createList([1,2,[21,22,[231],24,1],2,3,4,5])
上記を実行した結果は、
<1,2,<21,22,<231>,24,1>,2,3,4,5>
0コメント:
コメントを投稿