【问题标题】:Calculating weighted average from a list从列表中计算加权平均值
【发布时间】:2016-05-25 00:28:42
【问题描述】:

这是一个列表

[74.0, 96.0, 72.0, 88.0, ['71', '80', '83', '77', '90', '88', '95', '71', '76', '94'], 80.0, 74.0, 98.0, 77.0]

74以权重0.1计算,96以权重0.1计算,72以权重0.15计算,88以权重0.05计算,(71,80,83,77,90,88,95的平均值,71,76,94) 以 0.3 的重量计算,80 以 0.08 的重量计算,74 以 0.08 的重量计算,98 以 0.09 计算,最后 77 以 0.05 计算。每个分数都应乘以适当的权重。

这里是函数

def weighted_total_score(student_scores):
    return((int(student_scores[0])*.1)+(int(student_scores[1])*.1)+(int(student_scores[2])*.15)+(int(student_scores[3])*.05)+(int(student_scores[4][0])*.3)+(int(student_scores[5])*.08)+(int(student_scores[5])*.08)+(int(student_scores[5])*.09)+(int(student_scores[8])*.05))

预期值应该是 82.94,但我得到的是 78.48

【问题讨论】:

  • 有什么理由跳过student_scores[5]
  • 您的列表中有一个子列表。这可能是这里的问题。至少从似乎是这样的错误消息来看。
  • 另外,在修复第一个错误后,您会收到一个索引错误。你没有student_scores[9]
  • 您的预期输出是什么?另外,为什么将整数和列表混合在一起?这似乎是灾难的秘诀
  • 您可能想要概括您的函数,以便它可以使用不同于您硬编码的权重的权重。

标签: python weighted-average


【解决方案1】:

您正在切片外部列表:

student_scores[4:5][0]

切片生成一个新列表,在这种情况下,只有一个元素,[0] 选择 嵌套列表

>>> student_scores = [74.0, 96.0, 72.0, 88.0, ['71', '80', '83', '77', '90', '88', '95', '71', '76', '94'], 80.0, 74.0, 98.0, 77.0]
>>> student_scores[4:5]
[['71', '80', '83', '77', '90', '88', '95', '71', '76', '94']]
>>> student_scores[4:5][0]
['71', '80', '83', '77', '90', '88', '95', '71', '76', '94']

也许您想改用student_scores[4][0](没有切片,只有第 4 个元素)?那会产生'71':

>>> student_scores[4][0]
'71'

您也跳过了student_scores[5],将得到一个IndexError 对应的student_scores[9],但它并不存在。

您可能希望避免输入所有这些直接引用;将您的权重指定为一个序列,并使用 zip() 和生成器表达式和 sum() 来计算加权和:

def weighted_total_score(student_scores):
    weights = .1, .1, .15, .05, .3, .08, .08, .09, .05                 
    return sum(int(s[0] if isinstance(s, list) else s) * w
               for s, w in zip(student_scores, weights))

这使用isinstance(s, list) 来检测一个列表对象并从中提取第一个值。

如果您需要嵌套列表的平均值,请当场计算:

def average(string_scores):
    return sum(map(int, string_scores), 0.0) / len(string_scores)

def weighted_total_score(student_scores):
    weights = .1, .1, .15, .05, .3, .08, .08, .09, .05                 
    return sum(int(average(s[0]) if isinstance(s, list) else s) * w
               for s, w in zip(student_scores, weights))

这里的average() 函数将列表中的每个字符串转换为整数,然后将这些整数相加并将结果除以列表的长度。 sum() 以浮点 0.0 开头,强制总数为浮点数,这确保除法也产生浮点数,这只在 Python 2 上很重要。

【讨论】:

  • 谢谢!我会试试这个。我不知道如何在列表中为列表编制索引,该列表由 10 个需要一起平均的值组成。
  • @RachelSwamy:对,所以sum(map(int, nested_list)) / len(nested_list)?
  • @RachelSwamy:另外,这是 Python 2 还是 3?平均值也应该转换为整数吗?
  • 我刚刚使用 zip 尝试了上面的代码,它给了我 58.39 作为输出。我期待收到 81.94。我在这里哪里出错了。顺便说一句,我正在使用 python 3.5 @MartijnPieters
  • @RachelSwamy:我怎么知道哪里出了问题?您没有指定有关预期输出或计算方式的任何内容。输出对于权重和假设所有浮点数在乘以权重之前必须转换为 int() 是正确的。
猜你喜欢
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-14
  • 2021-11-21
  • 2017-04-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多