【问题标题】:The sum() function seems to be messing map objectssum() 函数似乎弄乱了地图对象
【发布时间】:2017-12-25 21:56:12
【问题描述】:

我正在做这个代码练习以尝试在 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)

heights 应该是一个地图对象,包含(或产生)两个现有高度条目的列表:[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() 函数不应该以任何方式更改地图对象,对吧?它仍然是一个地图对象,但不止一次在它上面调用 list() 似乎会改变它的行为。我很困惑。

【问题讨论】:

标签: python python-3.x dictionary sum


【解决方案1】:

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

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

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

编辑:另一种方法。

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

【讨论】:

  • 我想在这个答案中添加“生成器”的想法。这是wiki.python.org/moin/Generators的一些食物。
  • 好主意@ziyad,了解列表、迭代器和生成器之间的区别是必不可少的python知识!
  • 当我运行问题中给出的代码时,heights 确实给了我一个 [160, 80] 的列表,这是为什么呢?为什么代码对我来说运行完美?我正在使用 Python 2.7。
  • @FatihAkici 在 Python 2.7 中 map 将返回一个列表。见docs.python.org/2/library/functions.html#map
  • @juanpa.arrivillaga 是的,但是这个想法是非常相关的,对于阅读这个主题的人来说,引入一个生成器的想法会很有用。
【解决方案2】:

您可以通过迭代 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多