当你发现自己说“我想数数有多少……”时,很有可能Counter() https://docs.python.org/2/library/collections.html#collections.Counter, 来自collections
模块,可以提供帮助。
在本例中,我们想要计算每个字母出现在多少个列表中。由于我们不想对每个子列表多次计算任何字母,因此我们将它们转换为sets https://docs.python.org/2/tutorial/datastructures.html#sets:
>>> res = [['a', 'b', 'a'], ['a', 'b', 'c'], ['a']]
>>> [set(x) for x in res]
[{'b', 'a'}, {'c', 'b', 'a'}, {'a'}]
顺序会混淆,但这并不重要,只要每个列表中只有一个字母即可。
现在我们想将这些字母组合成一个序列,这样我们就可以对它们进行全部计数。我们可以这样做:
>>> [s for x in res for s in set(x)]
['b', 'a', 'c', 'b', 'a', 'a']
...但这有点难以理解。幸运的是,里面有一个函数itertools
模块称为chain() https://docs.python.org/2/library/itertools.html#itertools.chain它做同样的事情并且更容易阅读。我们想要chain.from_iterable()
版本:
>>> from itertools import chain
>>> c = chain.from_iterable(set(x) for x in res)
>>> list(c)
['b', 'a', 'c', 'b', 'a', 'a']
不用担心这个list(c)
太多了 -chain()
返回一个iterator https://docs.python.org/2/glossary.html#term-iterator,这意味着在我们实际对结果执行某些操作(例如将其放入列表中)之前,不会计算任何内容,因此我这样做是为了展示它产生的结果。
不管怎样,我们现在需要做的就是将该序列传递给Counter()
:
>>> from collections import Counter
>>> Counter(chain.from_iterable(set(x) for x in res))
Counter({'a': 3, 'b': 2, 'c': 1})
整个事情是这样的:
from collections import Counter
from itertools import chain
res = [['a', 'b', 'a'], ['a', 'b', 'c'], ['a']]
letter_count = Counter(chain.from_iterable(set(x) for x in res))
print(letter_count['a']) # prints 3