質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

286閲覧

辞書が上書きされてしまう

syen2501

総合スコア38

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/09/30 10:47

knpという構文解析システムを使用して、特定の属性を持つ語を抽出し、
辞書に追加するというプログラムを作成しているのですが、何故か
上書きされてしまいます。

python

1# -*- coding: utf-8 -*- 2import jctconv 3import semiformalizer 4 5def getDictforEditor(text): 6 number_of_time_list = [] #回数 7 strength_quantity_qualified_list = [] #強数量修飾 8 number_of_hours_list = [] #時数ノ 9 future_phrase_list = [] #未来句 10 quantity_list = [] #数量 11 strength_time_list = [] #強時間 12 time_list = [] #時間 13 dict_for_editor = {'回数':[],'強数量修飾':[],'時数ノ':[],'未来句':[],'数量':[],'強時間':[],'時間':[]} 14 tag = semiformalizer.MakeDict(text).tag() 15 prop = semiformalizer.MakeDict(text).prop() #tag,propはknpの情報を抜き出している 16 for i in prop.keys(): 17 if not (prop[i]['case'] is 'main' or prop[i]['case'] is 'obj' or prop[i]['type'] is 'action'): 18 if tag[i]['tag'].get('回数'): 19 number_of_time_list.append(prop[i]['midasi']) 20 elif tag[i]['tag'].get('強数量修飾'): 21 strength_quantity_qualified_list.append(prop[i]['midasi']) 22 elif tag[i]['tag'].get('時数ノ'): 23 number_of_hours_list.append(prop[i]['midasi']) 24 elif tag[i]['tag'].get('未来句'): 25 future_phrase_list.append(prop[i]['midasi']) 26 elif tag[i]['tag'].get('数量'): 27 quantity_list.append(prop[i]['midasi']) 28 elif tag[i]['tag'].get('強時間'): 29 strength_time_list.append(prop[i]['midasi']) 30 elif tag[i]['tag'].get('時間'): 31 time_list.append(prop[i]['midasi']) 32 # print(time_list) 33 dict_for_editor.update({'回数':number_of_time_list}) 34 dict_for_editor.update({'強数量修飾':strength_quantity_qualified_list}) 35 dict_for_editor.update({'時数ノ':number_of_hours_list}) 36 dict_for_editor.update({'未来句':future_phrase_list}) 37 dict_for_editor.update({'数量':quantity_list}) 38 dict_for_editor.update({'強時間':strength_time_list}) 39 dict_for_editor.update({'時間':time_list}) 40 # print(dict_for_editor) 41 return dict_for_editor 42 43 44if __name__ == '__main__': 45 dict_for_editor = [] 46 file = 'sample' 47 with open('{}.txt'.format(file),encoding = 'utf-8') as f: 48 text_list = f.readlines() 49 for text in text_list: 50 if not text == '\n' and not text is None: 51 text = ''.join(text.split()) # スペースを除く 52 text = jctconv.z2h(text,kana = False, digit = True, ascii = True) 53 dict_for_editor = getDictforEditor(text) 54 with open('{}の辞書.txt'.format(file),'w',encoding = 'utf-8') as f: 55 f.write(str(dict_for_editor)) 56 print(dict_for_editor)

<sample.txtの中身>
端末及びプリンターは、納入場所に現在設置しているものを使用すること。
献立業務において一ヶ月のカレンダー表示できること。

<出力結果>
{'回数': [], '強数量修飾': [], '時数ノ': ['一ヶ月の'], '未来句': [], '数量': [], '強時間': [], '時間': []}

理想としては、
{'回数': [], '強数量修飾': [], '時数ノ': ['一ヶ月の'], '未来句': [], '数量': [], '強時間': [], '時間': ['現在']}
1行目の結果は出てはいるのですが、2行目を読む際、上書きされるという結果が
起こっています。

原因としては、
・1行ずつknpの情報の判定をしているので、次の行の文章を読んだ際に上書きされる。
・それぞれ用意したリストにappendするときに上書きされる。
この2つが原因の候補になると思っています。
出来れば、助言をいただけると幸いです。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

コードが動かせないので検証はできないですが、辞書を関数の呼び出し元で定義するようにして、getDictforEditor() 関数に引数として渡してあげればいいのではないでしょうか?
追加するところは、dict_for_editor.update() ではなく、dict_for_editor['キー名'].append() とします。

辞書は参照渡しになるので、関数内で変更すれば、その結果が呼び出し元にも反映されます。

d = {'回数':[],'強数量修飾':[],'時数ノ':[],'未来句':[],'数量':[],'強時間':[],'時間':[]} def func(d): d['時間'].append('未来') func(d) func(d) print(d)
{'回数': [], '強数量修飾': [], '時数ノ': [], '未来句': [], '数量': [], '強時間': [], '時間': ['未来', '未来']}

追記

python

1array = ['未来', '未来', '過去', '現在'] 2 3# 重複した要素を除く 4array1 = list(set(array)) 5print(array1) # ['過去', '未来', '現在'] 6 7# 2個以上ある要素を除く 8array2 = [v for v in set(array) if array.count(v) == 1] 9print(array2) # ['過去', '現在']

投稿2018/09/30 11:05

編集2018/09/30 13:12
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

syen2501

2018/09/30 13:02

ありがとうございます。 無事に解決することが出来ました。 もう一つ質問なのですが、重複した要素を取り除く方法はありますか? set関数を使用してもうまくいかないのでよろしくお願いします。
tiitoi

2018/09/30 13:11

重複する要素を除くだけであれば、set() でできると思います。 それとも出現回数が1回の要素のみ残すということでしょうか? 回答に追記しましたので、意図と違ったら教えてください。
syen2501

2018/10/01 02:22

回答ありがとうございます。 もう一つ質問なのですが、上記で '時間': ['未来', '未来'] というのがあった場合、 set(d['時間'])で要素を削除できると思うのですが、この結果を辞書の方に更新 するにはどうしたらよいでしょうか?
tiitoi

2018/10/01 17:08

d = {'key': [1, 2, 3, 4, 5]} とした場合、 d['key'] = list(set(d['key'])) と代入し、更新すればよいです。dict.update() は辞書の連結に使う関数なので、辞書の値を更新するには、d['key'] = 値 と普通に代入します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問