【问题标题】:Difference between a 'for' loop and map“for”循环和映射之间的区别
【发布时间】:2019-01-11 06:13:01
【问题描述】:

从标题来看,是的,有区别。现在应用于我的场景:让我们考虑一个类Dummy

class Dummy:
    def __init__(self):
        self.attached = []

    def attach_item(self, item):
        self.attached.append(item)

如果我使用这个:

D = Dummy()
items = [1, 2, 3, 4]
for item in items:
    D.attach_item(item)

我确实得到了D.attached = [1, 2, 3, 4]。但如果我将函数attach_item 映射到itemsD.attached 仍然为空。

map(D.attach_item, items)

它在做什么?

【问题讨论】:

标签: python python-3.x function


【解决方案1】:

一个非常有趣的问题,有一个有趣的答案。

map 函数返回一个可迭代的 Map 对象。 map 正在懒惰地执行其计算,因此除非您迭代该对象,否则不会调用该函数。

如果你这样做:

x = map(D.attach_item, items)
for i in x:
    continue

会出现预期的结果。

【讨论】:

  • 如果你列出(x)则相同
  • @joaquin 这就是我被骗的地方。在我看来,在做list(x) 时,您希望将x 转换为列表。
  • @Mathieu 你会的。结果将是一个全无的列表。但作为副作用,该函数将修改 Dummy 对象的内部状态,这正是您想要的。一般来说,当你对副作用比对实际结果更感兴趣时,惰性求值不是很直观
  • @Ant 出于这个原因,我认为使用map 处理副作用是不好的编程风格。这是一种令人困惑的方式,OP的问题显示了这种困惑。
【解决方案2】:

map 只创建一个迭代器。您应该遍历它以将项目添加到D.attached。像这样:

D = Dummy()
items = [1, 2, 3, 4]
list(map(D.attach_item, items))

是的,不要在你的代码中这样做:) 但是这个例子只是有助于理解。

【讨论】:

  • 应该刚刚阅读过文档 x') 我以为我知道地图在做什么,结果我错了...谢谢!
【解决方案3】:

引用documentation

返回一个迭代器,它将函数应用于可迭代的每个项目,并产生结果。

这意味着你必须收集迭代器,例如

list(map(D.attach_item, items))

> [None, None, None, None]

嗯,奇怪。为什么没有,没有,...

是的,您可以在 map 语句中转换任何循环,但它并不总是有用。 Map 接受一个参数并对其进行处理(在大多数情况下)并返回它,没有副作用!这是一个例子:

def add(a):
    return a + 3
list(map(add, items))

> [4, 5, 6, 7]

真正的力量来了,当你将它与filter等其他功能结合使用时

def add(a):
    return a + 3
def odd(a):
    return a % 2 == 1
list(map(add, filter(odd, items)))

> [4, 6]

【讨论】:

  • 当我以前使用 map 时,总是在我需要从函数中捕获返回的情况下(即您的示例)。因此我申请了list()。我没有注意到 map 只是返回一个迭代器的事实:/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
  • 1970-01-01
  • 2015-11-18
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 2012-08-30
相关资源
最近更新 更多