sum()函数似乎弄乱了地图对象

时间:2017-12-25 21:56:13

标签: python python-3.x dictionary sum

我正在使用这个代码练习来尝试python中的函数式编程,我遇到了sum(),list()和map对象的问题。我不明白我做错了什么,但list()函数似乎搞砸了我的地图对象。

这是我的代码:

people = [{'name': 'Mary', 'height': 160},
          {'name': 'Isla', 'height': 80},
          {'name': 'Sam'}]

heights = map(lambda x: x['height'], filter(lambda x: 'height' in x, people))

print(len(list(heights)))
print(sum(list(heights)))
print(len(list(heights)))

average_height = sum(list(heights)) / len(list(heights))
print(average_height)

高度应该是一个地图对象,包含(或导致)两个现有高度条目的列表:[160,80]。

打印长度应该给2,两者的总和显然应该是240,平均值应该是120.

我面临的问题是,我收到此错误消息:

2
0
0
Traceback (most recent call last):
  File "C:\Users\Hugo\Dropbox\Programmering\PythonProjekt\exercise2.py", line 12, in <module>
    average_height = sum(list(heights)) / len(list(heights))
ZeroDivisionError: division by zero

是的,长度是正确的,但总和是0,第二长度打印也是0。整个零分割错误必须来自那里,并且似乎list()函数正在导致它。更改打印顺序仍然只能正确通过第一个打印语句:

print(sum(list(heights)))
print(len(list(heights)))
print(len(list(heights)))

给出:

240
0
0
Traceback (most recent call last):
  File "C:\Users\Hugo\Dropbox\Programmering\PythonProjekt\exercise2.py", line 12, in <module>
    average_height = sum(list(heights)) / len(list(heights))
ZeroDivisionError: division by zero

并删除list()函数:

print(sum(list(heights)))
print(len(heights))
print(len(list(heights)))

给了我:

240
Traceback (most recent call last):
  File "C:\Users\Hugo\Dropbox\Programmering\PythonProjekt\exercise2.py", line 9, in <module>
    print(len(heights))
TypeError: object of type 'map' has no len()

所以我不知道发生了什么。 list()函数不应该以任何方式更改map对象,对吧?它保留了一个map对象,但是不止一次调用它上面的list()似乎改变了它的行为。我很困惑。

2 个答案:

答案 0 :(得分:3)

实际上,调用list会改变您的map对象。 map是一个迭代器,而不是数据结构(在Python3中)。在它循环一次后,它就会耗尽。要重现结果,您需要重新创建地图对象。

在您的情况下,您可能想要做的是从地图创建一个列表来存储结果,然后执行sum

heights = list(heights)
average = sum(heights) / len(heights)

编辑:另一种方法。

您可以使用统计模块直接从迭代器计算算术平均值(和其他统计数据)。查看the docs

答案 1 :(得分:0)

您可以通过迭代map结构来创建列表,以避免在每次列表调用时耗尽迭代器:

people = [{'name': 'Mary', 'height': 160},
      {'name': 'Isla', 'height': 80},
      {'name': 'Sam'}]

heights = [i for i in map(lambda x: x['height'], filter(lambda x: 'height' in x, people))]
average_height = sum(heights)/len(heights)

输出:

120.0