3 回答

TA贡献1842条经验 获得超12个赞
别。它看起来就像使用字典推导的,这应该是一个不错的主意,但它实际上是一个可怕的陷阱。使用collections.Counter:
import counts
seen_dict = collections.Counter(ar)
或者如果你不想这样做,那就坚持循环。
尝试使用 dict 推导式的问题在于,dict 推导式没有很好的方法来维护状态或交错每个键的值的计算。每个值都必须在单个表达式中计算。相比之下,解决计数问题的最佳方法是进行单次传递ar并随时更新每个元素的计数。
理解的限制会导致非常低效的尝试,例如
seen_dict = {val: ar.count(val) for val in ar}
这使得传递的次数ar等于 的长度ar,或者稍微更有效但仍然非常不理想的
seen_dict = {val: ar.count(val) for val in set(ar)}
只需要len(set(ar))通过,或者对标准库比较熟悉的人,
from itertools import groupby
seen_dict = {val: sum(1 for _ in group) for val, group in groupby(sorted(ar))}
这至少不是二次时间,但对于 length-n 仍然是 O(nlogn) ar。
如果我们使用 input 对这四个片段进行计时list(range(10000)):
from collections import Counter
from itertools import groupby
from timeit import timeit
ar = list(range(10000))
print(timeit('Counter(ar)', number=1, globals=globals()))
print(timeit('{val: ar.count(val) for val in ar}', number=1, globals=globals()))
print(timeit('{val: ar.count(val) for val in set(ar)}', number=1, globals=globals()))
print(timeit('{val: sum(1 for _ in group) for val, group in groupby(sorted(ar))}',
number=1, globals=globals()))
我们得到以下输出:
0.0005530156195163727
1.0503493696451187
1.0463058911263943
0.00422721728682518
Counter在半毫秒内完成,而count片段都需要一秒钟。(该set版本似乎具有较低运行时,由于某种首轮效应减缓其他版本;交换的顺序set和非set版本通常逆转这些版本的相对定时的重复数据删除。set没有帮助这个测试,因为输入没有重复。)
对于更长的输入,依赖count将更加昂贵。依赖count可能很容易花费数天时间来输入Counter仍然可以在不到一秒的时间内完成。

TA贡献1852条经验 获得超7个赞
似乎您正在尝试获取列表中所有值的外观。(如果不是,请告诉我。)这是我的处理方法:
seen_dict = {num: arr.count(num) for num in list(set(arr))}
一个解释:
arr.count(num)
:list.count(element)
方法返回element
in的出现次数list
set(arr)
: 创建一个set
对象,当它转换回列表时会删除所有重复项,或者换句话说,获取列表的所有不同值list(set(arr))
: 中的不同值arr
字典回报将有键值对number
- # of appearances of number in arr
。
添加回答
举报