'for'循环和地图之间的区别

Mat*_*ieu 43 python function python-3.x

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

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

    def attach_item(self, item):
        self.attached.append(item)
Run Code Online (Sandbox Code Playgroud)

如果我用这个:

D = Dummy()
items = [1, 2, 3, 4]
for item in items:
    D.attach_item(item)
Run Code Online (Sandbox Code Playgroud)

我确实得到了D.attached = [1, 2, 3, 4].但是如果我将函数映射attach_itemitems,则D.attached保持为空.

map(D.attach_item, items)
Run Code Online (Sandbox Code Playgroud)

它在做什么?

小智 53

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

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

所以,如果你这样做:

x = map(D.attach_item, items)
for i in x:
    continue
Run Code Online (Sandbox Code Playgroud)

预期结果将显示出来.

  • @Ant因为这个原因,我认为使用`map`来产生副作用是糟糕的编程风格.这是一个令人困惑的方式,OP的问题显示了这种混乱. (10认同)
  • 如果你列出(x)相同 (8认同)
  • @Mathieu你这样做.结果将是一个完整的列表.但作为副作用,该函数将修改Dummy对象的内部状态,这正是您想要的.一般来说,当你对副作用比对实际结果更感兴趣时,懒惰评估不是很直观 (6认同)

Lev*_*rov 16

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

D = Dummy()
items = [1, 2, 3, 4]
list(map(D.attach_item, items))
Run Code Online (Sandbox Code Playgroud)

是的,不要在你的代码中这样做:)但这个例子对于理解是有用的.


hel*_*low 9

引用文档

返回一个迭代器,它将函数应用于每个iterable项,从而产生结果.

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

list(map(D.attach_item, items))

> [None, None, None, None]
Run Code Online (Sandbox Code Playgroud)

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

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

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

> [4, 5, 6, 7]
Run Code Online (Sandbox Code Playgroud)

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

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

> [4, 6]
Run Code Online (Sandbox Code Playgroud)