项目列表上的字典操作

时间:2016-05-29 21:27:04

标签: python performance dictionary hash iterator

我有一本字典

{ 'a': 1.0,
  'b': 1.1,
  'c': 0.9,
  # ...
  'z': 0.97
}

我有一个项目清单['a', 'b', 'c']。我想从字典中找到此列表的平均值。当然我可以遍历我的列表,找到并总结这些值,但有没有一种方法可以在没有for循环的情况下得到它?

3 个答案:

答案 0 :(得分:2)

来循环。但是你可以隐藏循环。

您可以使用operator.itemgetter() object为您执行此操作,例如:

from operator import itemgetter

average = sum(itemgetter(*list_of_keys)(your_dictionary)) / len(list_of_keys)

绝对明确:itemgetter()现在遍历您的键列表并生成具有相应值的元组。

另一个隐藏的'循环是map() function;使用dict.get()dict.__getitem__()作为要映射的函数,map()再次为您执行所有循环:

avegare = sum(map(your_dictionary.__getitem__, list_of_keys)) / len(list_of_keys)

此处dict.getdict.__getitem__之间的区别在于您丢失密钥时所获得的优势;第一个将导致TypeError,当您最终尝试将None和一个数字相加时,另一个会给您一个KeyError

否则,只需在生成器表达式中使用循环:

average = sum(your_dictionary[k] for k in list_of_keys) / len(list_of_keys)

演示:

>>> from operator import itemgetter
>>> d = {'a': 1.0, 'z': 0.97, 'c': 0.9, 'b': 1.1}
>>> selected = ['a', 'b', 'c']
>>> sum(itemgetter(*selected)(d)) / len(selected)
1.0
>>> sum(map(d.__getitem__, selected)) / len(selected)
1.0
>>> sum(d[k] for k in selected) / len(selected)
1.0

答案 1 :(得分:2)

如果你的dict被称为Items.Ordered <- CMdata$Items.Ordered orderGroup <- function(Items.Ordered) { Items.Ordered <- as.numeric(Items.Ordered) if (CMdata$Items.Ordered == 0) { return ("NONE") } else if (CMdata$Items.Ordered > 0 & CMdata$Items.Ordered <= 3) { return ("SMALL") } else if (CMdata$Items.Ordered > 3 & CMdata$Items.Ordered <= 8) { return ("MEDIUM") } else if (CMdata$Items.Ordered > 8) { return ("LARGE") } else { return ("OTHER") } } Order.Type <- NULL for (i in 1:nrow(CMdata)) { Order.Type <- c(Order.Type, orderGroup(CMdata[i,"Items.Orderd"])) } CMdata$Order.Type <- as.factor(Order.Type) 且你的列表被称为values,那么这是一个非常简短的解决方案:

items

请注意,这并不支持空的arithmetic_mean_inexact = sum(values[i] for i in items) / len(items) 列表,因为这会产生items。这很好,因为空序列的平均值实际上没有意义。

虽然这个解决方案表明在没有显式 for循环的情况下计算平均值是可能的,但它有一个问题,即对浮点数进行求和并将其除以大数会导致数值精度损失。修复这是非常重要的,需要更长的解决方案。幸运的是,Python 3.4(或更新版本)为此提供了统计模块,因此您应该使用statistics.mean()(正如另一个答案已经提出的那样)。例如:

ZeroDivisionError

根据您的具体问题,此功能中的其他功能可能更合适。您可以在documentation of the statistics module

中找到更多信息

答案 2 :(得分:2)

如果您使用的是python3,则可以使用 statistics.mean:

d = { "a": 1.0,
  "b": 1.1,
  "c": 0.9,

  "z": 0.97
}

lst = ["a", "b", "c"]
from statistics import mean


print(mean(map(d.get, lst)))

或者只使用sum:

print(sum(map(d.get, lst)) / len(lst))

假设lst中的所有项都在dict中,否则你会在添加float和NoneType时出错。