「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コメント:
コメントを投稿