【发布时间】:2014-01-21 13:38:23
【问题描述】:
我有一个这样的列表
L=['d','f','d','c','c','f','d','f']
我想计算 L 中出现了多少 d、f 和 c 并将结果存储为:
R=[['d',3],['f',3],['c',2]]
什么是最好的方法(算法)?
【问题讨论】:
标签: python
我有一个这样的列表
L=['d','f','d','c','c','f','d','f']
我想计算 L 中出现了多少 d、f 和 c 并将结果存储为:
R=[['d',3],['f',3],['c',2]]
什么是最好的方法(算法)?
【问题讨论】:
标签: python
最好的方法(算法),就是不要自己动手!
>>> from collections import Counter
>>> L=['d','f','d','c','c','f','d','f']
>>> Counter(L)
Counter({'d': 3, 'f': 3, 'c': 2})
如果你坚持要一份清单:
>>> Counter(L).items()
[('c', 2), ('d', 3), ('f', 3)]
【讨论】:
我觉得字典会更好:
>>> from collections import Counter
>>> L = ['d','f','d','c','c','f','d','f']
>>> Counter(L)
Counter({'d': 3, 'f': 3, 'c': 2})
但是,如果您坚持使用列表列表:
>>> L=['d','f','d','c','c','f','d','f']
>>> from collections import Counter
>>> var = Counter(L)
>>> [[key, value] for key, value in var.items()]
[['c', 2], ['d', 3], ['f', 3]]
【讨论】:
L=['d','f','d','c','c','f','d','f']
from collections import Counter
print Counter(L)
输出
Counter({'d': 3, 'f': 3, 'c': 2})
你可以使用Counter.most_common方法得到这样的结果
print Counter(L).most_common()
输出
[('d', 3), ('f', 3), ('c', 2)]
【讨论】:
在排序数据上使用itertools.groupby 的可能解决方案
实施
from itertools import groupby
[[k, len(list(v))] for k, v in groupby(sorted(L))]
输出
[['c', 2], ['d', 3], ['f', 3]]
性能比较
In [9]: L = [choice(ascii_letters) for _ in range(1000)]
In [10]: %timeit [[k, len(list(v))] for k, v in groupby(sorted(L))]
1000 loops, best of 3: 271 us per loop
In [11]: %timeit Counter(L).items()
1000 loops, best of 3: 306 us per loop
注意
需要注意的是,计数器解决方案中散列数据的开销超过了Tim's Sort中的排序复杂度
【讨论】: