多次元リストの話

Pythonで多次元リストを作るときと言えば、
a = [[0 for i in range(3)] for i in range(3)]
とリスト内包表記をすれば、
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

参考
http://d.hatena.ne.jp/greennoah/20081202/1228233338
http://php6.jp/python/basics/リスト内包表記/

とかなるわけだけど、例えば多次元リストの内側にくくられる(だいたい1次元目か2次元目)要素の数が「イテレーションの回数によって決定されるため、いくつか事前に決定できない時」とりあえずイテレーション中で得たデータを保持しておかなくてはいけません。

具体的には、
Wan na Learn English

という文を
[[(Wan,pos-tag),(na,pos-tag),(Learn,pos-tag),(English,pos-tag)], [ 次の文 ],[ 次の文 ]....]
のような形式に(タグをつけた上で)整形しなくてはいけない時。
(nltk.HiddenMarkovModelTrainer を利用するときに、この形に整形しなくてはいけないので)


一度、イテレーションで得たデータをとりあえず辞書化しておき、多次元リストを作るときに辞書を呼び出せば便利です。

例えば、
taple = (word,pos)
taple_dic[counter] = taple

と辞書を作っておきます。
counterはイテレーションの回数。

で多次元リストを作る時に
a= [taple_dic[i] for i in range(counter)]
counterは最終的にイテレーションが行われた回数。

とすれば [(word, pos-tag), (...),(...)] という形になり、これをさらに
sent_dic[counter_sent] = a

とでも辞書化して、またイテレーションの回数を記録しておけば、

b = [sent_dic[i] for i in range(counter_sent)]

で3次元構造が完成します。


イテレーションが関係する多次元リストの時は、辞書を使うとよい!

覚えておくと便利ですね。


あと、すごくわかりやすくてよくまとまってる多次元リストのまとめサイトが
http://www.panopticon.jp/blog/2008/02/162207.html

コードまで載ってるので助かりますです。


覚書に大切なとこをソースコードさらし

for line in sent_list:
taple_dic = {}
#繰り返し回数の制御用に。詳しくは下のほう参照
counter = 0
word_list = line.split()
if len(word_list) == 1:
continue
else:
for i in range(len(word_list)):

word = word_list[i]

if i == 0:
position = "BOS"
elif i == len(word_list)-1:
position = "EOS"
else:
position = 0

#pos_dicにない単語は飛ばす
if not word in pos_dic:
continue

else:
pos = pos_dic[word]

format = pos + "\t" + word + "\t" + str(i) +"\t" + str(position) + "\n"
#out.write(format)
#out.close()
#tapleの作成とtaple_dicの作成
taple = (word,pos)
taple_dic[counter] = taple

#symolsセットとtag_setのリストに出て来た語を追加する(重複しないように)
if not word in symbols:
symbols.append(word)
if not pos in tag_set:
tag_set.append(pos)

#iterationの制御用に(iはpos_dicにない単語は飛ばされるので、純粋
な繰り返し回数でない)
counter += 1



a= [taple_dic[i] for i in range(counter)]
sent_dic[counter_sent] = a
counter_sent += 1



b = [sent_dic[i] for i in range(counter_sent)]