我试图摆脱这个 for 循环,而是使用列表理解来给出相同的结果。
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)]
但这只会引发错误。谁能指出我正确的方向?
请您参考如下方法:
如果您想改变一个现有的列表/字典,使用列表/字典理解被认为是不好的风格,因为它会创建一个不必要的一次性列表/字典。
准确地说,我说的是以下内容:
>>> 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] - 应该使用列表理解来构建您实际需要的新列表
用字典理解创建一个新字典也很麻烦,因为不是每个值都应该递增(只有 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}
但是,我们现在的运行时复杂度不是最优的,因为对于 freqdist 中的每个键我们对 len(demo) 进行 O( demo ) 成员测试.
您可以使用set对于 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}
我也不认为这个解决方案特别优雅。
总之,您的 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})
这是我个人会使用的解决方案。
