San*_*uhh 1 python list-comprehension beautifulsoup nltk
我试图摆脱这个for循环,而是使用list comprehension来给出相同的结果.
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
Run Code Online (Sandbox Code Playgroud)
我不确定它是否可能,但由于+ = 1,我无法让它工作.我试过了:
[freqdist[word.lower()] +=1 for word in nltk.word_tokenize(raw)]
Run Code Online (Sandbox Code Playgroud)
但这只会引发错误.有人能指出我正确的方向吗?
如果你想改变一个现有的列表/字典,使用列表/字典理解被认为是坏样式,因为它创建了一个不必要的一次性列表/字典.
确切地说,我在谈论以下内容:
>>> 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}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,做你所描述的是可能的,但那不是你应该怎么做的原因
[None, None, None]
使用字典理解创建新字典也很麻烦,因为不是每个值都应该递增(只有那些值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}
Run Code Online (Sandbox Code Playgroud)
但是,我们现在的运行时复杂性不是很理想,因为freqdist
我们为每个键进行O(len(demo)
)成员资格测试demo
.
您可以使用set
for demo
来将字典构建的复杂性降低到O(len(freqdist)
),但前提是元素demo
是唯一的.
>>> 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}
Run Code Online (Sandbox Code Playgroud)
我认为这种解决方案也不是特别优雅.
总之,你的for
循环非常好.唯一不错的选择是使用Counter
您更新的对象:
>>> 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})
Run Code Online (Sandbox Code Playgroud)
这是我个人使用的解决方案.
归档时间: |
|
查看次数: |
580 次 |
最近记录: |