2015-10-08 10 views
15

私はリストのリストをテキストでいっぱいのpythonで持っています。それは各文書からの言葉のようなものです。だから、すべてのドキュメントのために私はリストを持っているし、すべてのドキュメントのリストです。どのように辞書の理解を使用して文書内の各単語の出現を数えることができます

すべてのリストにはユニークな単語しか含まれていません。 私の目的は、完全な文書の各単語の出現を数えることです。

for x in texts_list: 
    for l in x: 
     if l in term_appearance: 
      term_appearance[l] += 1 
     else: 
      term_appearance[l] = 1 

しかし、私は同じことをするために辞書の理解を使いたいと思います。これが初めてです、私は次のように記述することができた、辞書理解を書き込もうとstackoverflowの中に、以前の既存の投稿を使用しています:参照用

from collections import defaultdict 
term_appearance = defaultdict(int) 

{{term_appearance[l] : term_appearance[l] + 1 if l else term_appearance[l] : 1 for l in x} for x in texts_list} 

前の投稿:

Simple syntax error in Python if else dict comprehension

{{l : term_appearance[l] + 1 if l else 1 for l in x} for x in texts_list} 

上記のコードは、PRに成功した:上記の記事で示唆したように

は、私はまた、次のコードを使用しています私の現在の理解を向上させることで任意の助けをいただければ幸いです

[] 

[] 

[] 

[] 

Traceback (most recent call last): 

    File "term_count_fltr.py", line 28, in <module> 

    {{l : term_appearance[l] + 1 if l else 1 for l in x} for x in texts_list} 
    File "term_count_fltr.py", line 28, in <setcomp> 

    {{l : term_appearance[l] + 1 if l else 1 for l in x} for x in texts_list} 

TypeError: unhashable type: 'dict' 

:最終的には空のリストをoducingが、は、次のトレースバックを投げました。

は、上記のエラーを見て、私はまた、これはエラーなしで走った

[{l : term_appearance[l] + 1 if l else 1 for l in x} for x in texts_list] 

を試してみましたが、出力は空のリストでした。

+0

幸運が...ここで考えられている、デフォルトの辞書は、あなたがもし、他の部分を必要としない場合があります意味するゼロにデフォルト設定されます。 – nehemiah

答えて

12

他の回答で説明したように、問題は、辞書の補完によって新しい辞書が作成されるため、作成されるまでその新しい辞書への参照を取得しないことです。あなたは何をしているのかについての辞書の理解はできません。

あなたがやっていることは、すでに行われていることをcollections.Counterで再実装しようとしていることです。あなたは単にCounterを使うことができます。例 -

from collections import Counter 
term_appearance = Counter() 
for x in texts_list: 
    term_appearance.update(x) 

デモ -

>>> l = [[1,2,3],[2,3,1],[5,4,2],[1,1,3]] 
>>> from collections import Counter 
>>> term_appearance = Counter() 
>>> for x in l: 
...  term_appearance.update(x) 
... 
>>> term_appearance 
Counter({1: 4, 2: 3, 3: 3, 4: 1, 5: 1}) 

あなたが本当に理解のいくつかの種類でこれを実行したい場合は、あなたが行うことができます:

from collections import Counter 
term_appearance = Counter() 
[term_appearance.update(x) for x in texts_list] 

デモ -

>>> l = [[1,2,3],[2,3,1],[5,4,2],[1,1,3]] 
>>> from collections import Counter 
>>> term_appearance = Counter() 
>>> [term_appearance.update(x) for x in l] 
[None, None, None, None] 
>>> term_appearance 
Counter({1: 4, 2: 3, 3: 3, 4: 1, 5: 1}) 

出力は[None, None, None, None]です。リスト内でのリストの理解(対話的に実行されているため)、python <script>というスクリプトでこれを実行すると、その出力は単に破棄されます。


また、あなたのtext_listsから平らにリストを作成し、カウンターのためにそれを使用するitertools.chain.from_iterable()を使用することができます。例:

from collections import Counter 
from itertools import chain 
term_appearance = Counter(chain.from_iterable(texts_list)) 

デモ -

>>> from collections import Counter 
>>> from itertools import chain 
>>> term_appearance = Counter(chain.from_iterable(l)) 
>>> term_appearance 
Counter({1: 4, 2: 3, 3: 3, 4: 1, 5: 1}) 

はまた、ラインであなたの元のコードでは別の問題 -

{{term_appearance[l] : term_appearance[l] + 1 if l else term_appearance[l] : 1 for l in x} for x in texts_list} 

は、これは実際にネストされた辞書の理解とセットの理解であります内部。

これは、エラーが発生した理由です。TypeError: unhashable type: 'dict'です。最初に辞書の理解を実行してdictを作成した後、それをsetに追加しようとしているためです。しかし、辞書はハッシュ可能ではないため、エラーです。

6

unhashable型のエラーが発生するのは、Pythonで別の辞書のキーとして辞書を使用することができないということです。

参照:Pythonの2.7以降でwhy dict objects are unhashable in python?

3

辞書内包表記は、あなたは、彼らが働くと思うかもしれように動作しません。リストの内包表記と同様に

は、彼らが新しい辞書を作成していますが(このケースでは、あなたがやろうとしているものです)すでに既存辞書にキーを追加するためにそれらを使用することはできません。

3

answerAnand S Kumarを確認してください。collections.Counterを使用するとよいでしょう。しかし、私が言及する価値がある見つけるcollections.defaultdictの使用に関連する別の解決策があります:

from collections import defaultdict 

text_appearances = defaultdict() 

for x in texts_lists: 
    for l in x: 
     text_appearances[l] += 1 

私は、これは、いくつかの回を構築使用しました、と私は、カウントを行うためのクリーンで良い方法だと思います。特に何らかの理由でループ内で何らかの検証を行う必要がある場合は、キー/単語が(最初の解決策のように)辞書にすでに存在するかどうかを気にせずに直接カウントを更新する効果的な方法です。変数の命名上の

追記:変数名として小文字lLの小文字)を使用しないでください、1(数1)から区別することは困難です。あなたの場合、おそらく変数にはwordswordという名前を付けることができますか?接尾辞として_listを使用していないの追加により、コードが読むことができる:

for words in texts: 
    for word in words: 
     text_appearance[word] += 1 
関連する問題