繁体   English   中英

转换字典值的有效方法

[英]Efficient way to transform dict values

例如,假设我正在计算某些类别中某些变量的平均值。 实现此计算的一种方法如下:

from collections import defaultdict

avg = defaultdict(lambda:[0,0])
for cat_name, val in data:
    cat = avg[cat_name]
    cat[0] += 1
    cat[1] += val

avg = { cat: s/n for cat,(n,s) in avg.items() }

这需要从原始字典创建一个新字典。

或者,除法可以像这样在循环中完成:

for cat,(n,s) in avg.items():
    avg[cat] = s/n

这不会创建新字典 object,但需要在每次迭代时进行键查找,这具有相同的复杂性。

问题是,不需要更改字典的结构,因此实际上不需要 hash 表查找。 旧值可以直接替换新值。 但这可以在 python 中完成吗?

在 C++20 中,可以按照以下方式做一些事情:

std::unordered_map<std::string,std::variant<std::tuple<unsigned,double>,double>> avg;
// loop over data to accumulate counts and sums
for (auto& [cat,x] : avg) {
  auto [n,s] = x.get<0>();
  x = s/n;
}

就地转换字典值。

有没有办法在 python 中做类似的事情?


附录:我只用计算平均值的问题作为一个具体的例子。 问题是关于字典值的有效转换。

虽然list可用于模拟引用类型,但我正在考虑的解决方案是获取对字典 object 的底层存储的可变访问权限。类似于items()方法,但返回的是可变内容tuple s。 或者可能是一个 function 接受一个dict和一个回调 function 用于转换值,a la map ,但就地。 如果散文不清楚,可以使用以下内容:

for x in dict_instance.mutable_items():
    x.value = x.value[1]/x.value[0]

或者

dict_instance.transform_values(lambda v: v[1]/v[0])

附录 2 :我也意识到我可以通过这样做来改变原始列表元素之一的含义,比如从总和到平均值:

for val in avg.values():
    val[1] = val[1]/val[0]

我想知道是否有办法替换整个值 object 并避免查找。

实际上,您可以使用列表技巧。

from collections import defaultdict
# You use list object for average
avg = defaultdict(lambda:[0,0, list([0])])
for cat_name, val in data:
    cat = avg[cat_name]
    cat[0] += 1
    cat[1] += val

for _, (s, n, lst) in avg.items():
    lst[0] = s / n

该解决方案不需要密钥查找,但会增加 memory 的使用。

或者

如果total of val 变量只是使用平均过程,则可以使用增量平均。

David Silver 演讲幻灯片中的增量均值公式在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM