2017-05-02 16 views
1

私はこのforループを取り除き、代わりにリスト内包を使用して同じ結果を得ようとしています。リスト内包表記を使用して辞書の値に1を加算する

fd= nltk.FreqDist() 
html = requests.get("http://www.nrc.nl/nieuws/2015/04/19/louise-gunning-vertrekt-als-voorzitter-bestuur-uva/") 
raw = BeautifulSoup(html.text).text 
for word in nltk.word_tokenize(raw): 
    freqdist[word.lower()] += 1 

可能かどうかはわかりませんが、+ = 1のため動作できません。私は試しました:

[freqdist[word.lower()] +=1 for word in nltk.word_tokenize(raw)] 

しかし、それはエラーを発生させます。誰かが私を正しい方向に向けることができますか?

+3

[カウンタ](httpsを使用します: //docs.python.org/2/library/collections.html#collections.Counter)? – asongtoruin

+0

リスト内包は新しいリストを作成します。ここでリストを作成したいとは思われません。 – ikkuh

+5

'for'ループの何が問題ですか?リスト内包表記は、リストを作成するためのものであり、 'for'ループの代用品ではありません。あなたが副作用を利用しようとしているように見えます。 – roganjosh

答えて

5

に変更する場合は、既存のリスト/ディクショナリを使用します。リスト/ディクショナリの使用は、不要なスローアウェイリスト/ディクショナリを作成するため、不適切なスタイルとみなされます。

正確には、私は次のについて話している:あなたが見ることができるように

>>> demo = ['a', 'b', 'c'] 
>>> freqdist = {'a': 0, 'b': 1, 'c': 2} 
>>> [freqdist.__setitem__(key, freqdist[key] + 1) for key in demo] 
[None, None, None] 
>>> freqdist 
{'a': 1, 'c': 3, 'b': 2} 

は、あなたが可能である記述する何をして、それはあなたが何をすべきかではありません、それ

  • 理由それは読むのが難しい
  • それは未使用のスローアウェイリストを作成します[None, None, None]
  • あなたは実際には新しいリストを構築するためにリストの補完を使用する必要がありますeed

辞書の理解度を持つ新しい辞書を作成することは、すべての値をインクリメントする必要はないため(唯一の単語はdemo)、迷惑です。 freqdistの各キーのために私たちはdemoためのO(len(demo))メンバーシップのテストを行うため

あなたは

>>> demo = ['a', 'b', 'c'] 
>>> freqdist = {'a': 0, 'b': 1, 'c': 2} 
>>> freqdist = {k:v + (k in demo) for k,v in freqdist.items()} 
>>> freqdist 
{'a': 1, 'c': 3, 'b': 2} 

を行うしかし、我々は今、次善のランタイムの複雑さを持つことができます。

あなたが、demoの要素が一意である場合にのみ、O(len(freqdist))に辞書建物の複雑さを軽減するためにdemoためsetを使用することができます。

>>> demo = set(['a', 'b', 'c']) 
>>> freqdist = {'a': 0, 'b': 1, 'c': 2} 
>>> freqdist = {k:v + (k in demo) for k,v in freqdist.items()} 
>>> freqdist 
{'a': 1, 'c': 3, 'b': 2} 

私はこの解決法も特に優雅だとは思わない。

結論として、あなたのforループは完璧です。これは私が個人的に使用するソリューションです

>>> from collections import Counter 
>>> demo = ['a', 'b', 'c'] 
>>> freqdist = Counter({'a': 0, 'b': 1, 'c': 2}) 
>>> freqdist.update(demo) 
>>> freqdist 
Counter({'c': 3, 'b': 2, 'a': 1}) 

:唯一の良い選択肢は、あなたが更新Counterオブジェクトを使用することです。

0

これは動作します:あなたがcollections.Counterを使用することはできないある場合

>>> txt = 'Hello goodbye hello GDby Dog cat dog' 
>>> txt_new = txt.lower().split() 
>>> print txt_new 
['hello', 'goodbye', 'hello', 'gdby', 'dog', 'cat', 'dog'] 

collections

>>> import collections 
>>> collections.Counter(txt_new) 
Counter({'hello': 2, 'dog': 2, 'gdby': 1, 'cat': 1, 'goodbye': 1}) 

を使用します。

>>> {word: txt_new.count(word) for word in set(txt_new)} 
{'goodbye': 1, 'dog': 2, 'hello': 2, 'gdby': 1, 'cat': 1} 
関連する問題