【问题标题】:Count number of words that start with a letter Python [closed]计算以字母Python开头的单词数[关闭]
【发布时间】:2014-01-02 16:51:01
【问题描述】:

我正在尝试计算列表中以字母表中每个字母开头的单词数。我尝试了很多东西,但似乎没有任何效果。最终结果应该是这样的:

list = ['the', 'big', 'bad', 'dog']
a: 0
b: 2
c: 0
d: 1

我想我应该用字典做点什么,对吧?

【问题讨论】:

  • 到目前为止你的代码是什么样的?您面临哪个问题?
  • 是的。 dict 是实现的选择之一。

标签: python dictionary count


【解决方案1】:

作为说明,我展示了一个来自第三方库 pandas 的示例,以展示 Python 世界中与标准集合或构建的 itertools 类型不同的一些选项-in 选项。我认为这个答案是次要的、着色的答案,而不是主要答案。

Pandas 的网站在这里:

http://pandas.pydata.org/

pandas 可以通过以下设置工具轻松获得:

$ pip install pandas

pandas 的目的是快速和syntactically sweet 数据分析,就像您在 R 或 Microsoft Excel 等电子表格程序中所期望的那样。它由 Wes McKinney 和一个由其他贡献者组成的小团队不断开发,并以 BSD 级别的许可发布 - 这意味着它通常可以在您自己的项目中免费使用,无论是商业项目还是其他项目,只要您的属性正确。

pandas 的一个优势是它在这种情况下的语法非常清晰(value_counts),并且它的实现非常快,比原生 Python 快得多:

from pandas import Series

sample_list = ['the', 'big', 'bad', 'dog']
s = Series([word[0] for word in sample_list])
s.value_counts()

返回:

b    2
d    1
t    1

让我们来:

In [19]: len(big_words)
Out[19]: 229779

一个熊猫实现:

def count_first(words):
    s = Series([word[0] for word in words])
    return s.value_counts()

In [15]: %timeit count_first(big_words)
10 loops, best of 3: 29.6 ms per loop

上面接受的答案:

def counter_first(words):
   return Counter(s[0] for s in words)

%timeit counter_first(big_words)
10 loops, best of 3: 105 ms per loop

速度明显更快,即使在函数中使用列表转换也是如此。通过强制列表转换,我们对 pandas 不公平。假设我们从一个系列开始来解决这个问题。

In [20]: s = Series([word[0] for word in words])

In [21]: %timeit s.value_counts()
1000 loops, best of 3: 406 µs per loop

这是 258.6 倍的速度提升。

我什么时候会考虑使用 pandas 而不是 Counter?

垃圾邮件分类器就是一个很好的例子。如果您正在处理自然语言处理问题并且需要通过以单个字母开头的单词的相对流行度来分析单词选择,并且您正在查看数以百万计的单词的数千封电子邮件和/或网站,那么使用 pandas 会加快速度会很重要。

最重要的是,pandas 是一个性能更高的库,但需要一点包管理(基于 Python 或 os)才能获得。

【讨论】:

  • 问这个问题的人应该是菜鸟,应该是想了解python,所以pandas不是回答这个问题的方法
  • 当然,这就是答案被接受并且投票率更高的原因。完全有可能有人会用数百万字来尝试这个,并想知道为什么它这么慢。我看不出在混合中提供不同颜色的答案有什么问题。
  • 我建议您通过解释什么是 pandas 库并链接到文档来编辑您的答案。在那种情况下,我一定会改变我的看法。
  • 这很公平。感谢您的来回富有成效!
  • +1 Counter 是这个问题的标准答案。我从没想过使用 pandas,我喜欢这个例子,并认为它对未来的访问者(比如我!)很有说明性。 3 倍的加速提醒我们,高级构造不需要为了性能而牺牲可读性。
【解决方案2】:
In [63]: %%timeit
....: from collections import defaultdict
....: fq = defaultdict( int )
....: for word in words:
....:        fq[word[0].lower()] += 1
....:
10 loops, best of 3: 138 ms per loop


In [64]: %%timeit
....: from collections import Counter
....: r = Counter(word[0].lower() for word in words)
....:
1 loops, best of 3: 287 ms per loop

In [65]: len(words)
Out[65]: 235886

词源来自/usr/share/dict/words。以上demo使用了IPythontimeit函数。

In [68]: fq
Out[68]:defaultdict(<type 'int'>, {'a': 17096, 'c': 19901, 'b': 11070, 'e': 8736, 'd': 10896, 'g': 6861, 'f': 6860, 'i': 8799, 'h': 9027, 'k': 2281, 'j': 1642, 'm': 12616, 'l': 6284, 'o': 7849, 'n': 6780, 'q': 1152, 'p': 24461, 's': 25162, 'r': 9671, 'u': 16387, 't': 12966, 'w': 3944, 'v': 3440, 'y': 671, 'x': 385, 'z': 949})

我建议使用defaultdict,因为它的方法简单且速度更快。

n [69]: %%timeit
....: d = {}
....: for word in words:
....:        key = word[0].lower()
....:        if key in d:
....:                d[key] += 1
....:        else:
....:                d[key] = 1
....:
1 loops, best of 3: 177 ms per loop

Counter 相比,普通方法似乎也更快,但几乎没有额外的代码行。

【讨论】:

  • 哈哈哈!!!这将usually be me 发布时间!!! :-) 需要注意的一点:柜台最近进行了大修。在 Python 3.3.3 中,在链接测试中,f5 - 计数器从最慢变为最快。我取决于设置时间的摊销、数据的大小、键的数量、丢失的键的数量和 Python 版本。
【解决方案3】:
from collections import Counter
print Counter(s[0] for s in  ['the', 'big', 'bad', 'dog'])
# Counter({'b': 2, 't': 1, 'd': 1})

如果你想要零,你可以这样做:

import string

di={}.fromkeys(string.ascii_letters,0)
for word in ['the', 'big', 'bad', 'dog']:
    di[word[0]]+=1

print di    

如果你只是想让'A''a' 一样:

di={}.fromkeys(string.ascii_lowercase,0)
for word in ['the', 'big', 'bad', 'dog']:
    di[word[0].lower()]+=1
# {'a': 0, 'c': 0, 'b': 2, 'e': 0, 'd': 1, 'g': 0, 'f': 0, 'i': 0, 'h': 0, 'k': 0, 'j': 0, 'm': 0, 'l': 0, 'o': 0, 'n': 0, 'q': 0, 'p': 0, 's': 0, 'r': 0, 'u': 0, 't': 1, 'w': 0, 'v': 0, 'y': 0, 'x': 0, 'z': 0}

您可以将这两者结合起来:

c=Counter({}.fromkeys(string.ascii_lowercase,0))
c.update(s[0].lower() for s in  ['the', 'big', 'bad', 'dog'])
print c
# Counter({'b': 2, 'd': 1, 't': 1, 'a': 0, 'c': 0, 'e': 0, 'g': 0, 'f': 0, 'i': 0, 'h': 0, 'k': 0, 'j': 0, 'm': 0, 'l': 0, 'o': 0, 'n': 0, 'q': 0, 'p': 0, 's': 0, 'r': 0, 'u': 0, 'w': 0, 'v': 0, 'y': 0, 'x': 0, 'z': 0})

【讨论】:

  • 他想要a: 0 和所有这些:(
【解决方案4】:
myList = ["the", "big", "bad", "dog"]
from string import ascii_lowercase
d = dict.fromkeys(ascii_lowercase, 0)
for item in myList:
    d[item[0]] += 1
print d

输出

{'a': 0, 'c': 0, 'b': 2, 'e': 0, 'd': 1, 'g': 0, 'f': 0, 'i': 0, 'h': 0, 'k': 0, 'j': 0, 'm': 0, 'l': 0, 'o': 0, 'n': 0, 'q': 0, 'p': 0, 's': 0, 'r': 0, 'u': 0, 't': 1, 'w': 0, 'v': 0, 'y': 0, 'x': 0, 'z': 0}

【讨论】:

    猜你喜欢
    • 2020-07-28
    • 2018-09-03
    • 2023-02-21
    • 2020-10-31
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多