为了账号安全,请及时绑定邮箱和手机立即绑定

使用字典理解增加字典值

使用字典理解增加字典值

小唯快跑啊 2021-06-17 18:08:15
我正在尝试使用 dict 理解和 python 中的三元运算来执行以下表达式:for num in ar:     if num in seen_dict:         seen_dict[num] += 1     else:         seen_dict[num] = 1我试过这个:seen_dict = { num: seen_dict[num] += 1 for num in ar if num in seen_dict else seen_dict[num] = 1}及其几个排列,但我不断收到语法错误。可以做我想做的吗?更新这是正确的语法,但不是我的 dict 只返回 1: seen_dict = { num: (seen_dict[num] + 1) if num in seen_dict else 1 for num in ar }有人可以解释为什么这与 for 循环的功能不同吗?谢谢你。
查看完整描述

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仍然可以在不到一秒的时间内完成。



查看完整回答
反对 回复 2021-06-22
?
慕姐4208626

TA贡献1852条经验 获得超7个赞

似乎您正在尝试获取列表中所有值的外观。(如果不是,请告诉我。)这是我的处理方法:

seen_dict = {num: arr.count(num) for num in list(set(arr))}

一个解释:

  • arr.count(num):list.count(element)方法返回elementin的出现次数list

  • set(arr): 创建一个set对象,当它转换回列表时会删除所有重复项,或者换句话说,获取列表的所有不同值

  • list(set(arr)): 中的不同值 arr

字典回报将有键值对number# of appearances of number in arr


查看完整回答
反对 回复 2021-06-22
  • 3 回答
  • 0 关注
  • 133 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号