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

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

ただいまの
回答率

87.77%

[python]辞書のvaluesを、部分的に別の辞書のvaluesにする方法(多重リスト)

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 274

score 6

概要

pythonの関数から、求める返り値が得られません。下記のようにうまくいっておりません。
正しい返り値を得るために、『修正したいコード』をどのように良くできるか、アドバイスをいただければ幸いです。

修正したいコード

この関数内で使用した関数は、下の『使用した関数』に記載しております。

#関数
#入力;[['**','***'],['*','***'],['****','*']]という形の二重リスト
#出力;二重リストに含まれる語の出現回数をvalueとする辞書のリスト(下に記載されたようなものです)
def total_word_count(timelines1):
    total_word_dict={}
    total_word_count_l=[]

    for TL in timelines1:
        TL2SL=timeline2stemDict(TL)
        total_word_count_l.append(TL2SL)
        for word in TL2SL:
            if word not in total_word_dict:
                total_word_dict[word]=0
    print(total_word_count_l)
    print()
    print(total_word_dict)
    print()

    total_word_dict_list=[total_word_dict]*len(total_word_count_l)

    for i in range(len(total_word_count_l)): 
        for Word in total_word_dict:
            if Word in total_word_count_l[i]:
                n=total_word_count_l[i][Word]
                total_word_dict_list[i][Word]=n
            else:
                total_word_dict_list[i][Word]=0

    return total_word_dict_list

修正したいコードの試用

sample_timelines=[['みかん、餅を食べた','美味しい'],['みかんを食べた','美味しい'],['消しゴムを食べた','まずい']]
print(total_word_count(sample_timelines))
#出力 

#total_word_count_l
[{'みかん': 1, '、': 1, '餅': 1, 'を': 1, '食べる': 1, 'た': 1, '美味しい': 1},
 {'みかん': 1, 'を': 1, '食べる': 1, 'た': 1, '美味しい': 1}, 
{'消しゴム': 1, 'を': 1, '食べる': 1, 'た': 1, 'まずい': 1}]

#total_word_dict
{'みかん': 0, '、': 0, '餅': 0, 'を': 0, '食べる': 0, 'た': 0, '美味しい': 0, '消しゴム': 0, 'まずい': 0}
#ここまでは得たい結果が得られています。

#total_word_dict_list
[{'みかん': 0, '、': 0, '餅': 0, 'を': 1, '食べる': 1, 'た': 1, '美味しい': 0, '消しゴム': 1, 'まずい': 1},
 {'みかん': 0, '、': 0, '餅': 0, 'を': 1, '食べる': 1, 'た': 1, '美味しい': 0, '消しゴム': 1, 'まずい': 1},
 {'みかん': 0, '、': 0, '餅': 0, 'を': 1, '食べる': 1, 'た': 1, '美味しい': 0, '消しゴム': 1, 'まずい': 1}]


この最後のリストtotal_word_dict_listが、求めるものではありません。

代わりに得たい結果は、次のようなものです。

#total_word_dict_list
[{'みかん': 1, '、': 0, '餅': 1, 'を': 1, '食べる': 1, 'た': 1, '美味しい': 1, '消しゴム': 0, 'まずい': 0},
 {'みかん': 1, '、': 0, '餅': 0, 'を': 1, '食べる': 1, 'た': 1, '美味しい': 1, '消しゴム': 0, 'まずい': 0},
 {'みかん': 0, '、': 0, '餅': 0, 'を': 1, '食べる': 1, 'た': 1, '美味しい': 0, '消しゴム': 1, 'まずい': 1}]


total_word_dictに、total_word_count_lの各要素を重ね合わせたような形が、求めるものです。

使用した関数

修正したいコードの中で使用した関数は、下の二つになります。これらが機能することは確認済みです。

import MeCab

#関数
#入力;文字列
#出力;形態素解析の結果である二重リスト
def mecab_list(text):
    tagger = MeCab.Tagger("-Ochasen")
    tagger.parse('')
    node = tagger.parseToNode(text)
    mecab_output = []
    while node:
        word = node.surface
        wclass = node.feature.split(',')
        if wclass[0] != u'BOS/EOS':
            if wclass[6] == None:
                mecab_output.append([word,wclass[0],wclass[1],wclass[2],""])
            else:
                mecab_output.append([word,wclass[0],wclass[1],wclass[2],wclass[6]])
        node = node.next
    return mecab_output

#確認
print(mecab_list('昨日買った犬は寝ていた'))
#結果
[['昨日', '名詞', '副詞可能', '*', '昨日'], ['買っ', '動詞', '自立', '*', '買う'], ['た', '助動詞', '*', '*', 'た'], ['犬', '名詞', '一般', '*', '犬'], ['は', '助詞', '係助詞', '*', 'は'], ['寝', '動詞', '自立', '*', '寝る'], ['て', '助詞', '接続助詞', '*', 'て'], ['い', '動詞', '非自立', '*', 'いる'], ['た', '助動詞', '*', '*', 'た']]
#関数
#入力;['----',...,'@@@@@']という形状のリスト
#返り値;辞書。mecabで抽出した語幹をkeyに、timelineにその語が出現した回数をvalueに持つ。
def timeline2stemDict(timeline):
    timeline_d={}
    for twt in timeline:
        twtML=mecab_list(twt)
        for i in range(len(twtML)):
            if twtML[i][4] in timeline_d:
                timeline_d[twtML[i][4]]+=1
            else:
                timeline_d[twtML[i][4]]=1
    return timeline_d

#確認
sample_timeline=['昨日の朝ごはんは非常に美味しかった。','明日のお昼ご飯は美味しく作ることができるかな?','今日も早めに寝ることにしよう。']
print(timeline2stemDict(sample_timeline))
#結果
{'昨日': 1, 'の': 2, '朝': 1, 'ごはん': 1, 'は': 2, '非常': 1, 'に': 3, '美味しい': 2, 'た': 1, '。': 2, '明日': 1, 'お昼': 1, 'ご飯': 1, '作る': 1, 'こと': 2, 'が': 1, 'できる': 1, 'か': 1, 'な': 1, '?': 1, '今日': 1, 'も': 1, '早め': 1, '寝る': 1, 'する': 1, 'う': 1}

環境

Jupiter-notebook
macOS Catalina

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • meg_

    2019/12/28 12:54

    ロジックは出来ていて、コードに落とせないということですか?

    キャンセル

  • Yoocie

    2019/12/28 14:08

    はい。ロジックはできていると思います。

    キャンセル

回答 1

checkベストアンサー

0

下記部分が問題かと思います。

 total_word_dict_list=[total_word_dict]*len(total_word_count_l)

簡単な例です。

l = [1,2,3]
l2 = [l] * 2
#l2 = [[1,2,3],[1,2,3]]

l2[0][0] = 100
#l2 = [[100,2,3],[100,2,3]]

質問のコード中で「total_word_dict_list[i][Word] = XXX」にて値が上書きされているかと思います。
デバッグして確かめてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/12/28 20:16

    返信遅くなりました。上手く出来ました。大変貴重なご指摘、有難うございました。

    キャンセル

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

  • ただいまの回答率 87.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る