Difference between a 'for' loop and map
Question:
From the title, yes there is a difference. Now applied to my scenario: let’s consider a class Dummy
:
class Dummy:
def __init__(self):
self.attached = []
def attach_item(self, item):
self.attached.append(item)
If I use this:
D = Dummy()
items = [1, 2, 3, 4]
for item in items:
D.attach_item(item)
I indeed get D.attached = [1, 2, 3, 4]
. But if I map the function attach_item
to the items
, D.attached
remains empty.
map(D.attach_item, items)
What is it doing?
Answers:
map
only creates an iterator. You should iterate through it to add items into D.attached
. Like this:
D = Dummy()
items = [1, 2, 3, 4]
list(map(D.attach_item, items))
Yep, don’t do it in your code:) But the example is just useful for understanding.
Quoting the documentation
Return an iterator that applies function to every item of iterable, yielding the results.
which means you have to collect the iterator, e.g.
list(map(D.attach_item, items))
> [None, None, None, None]
Hmmm, strange. Why None, None, …
Yes, you can convert any loop in a map statement, but it’s not always useful.
Map takes a parameter and does something with it (in most cases) an returns it, without side effects! Here’s an example:
def add(a):
return a + 3
list(map(add, items))
> [4, 5, 6, 7]
The true power comes, when you combine it with other functions like filter
def add(a):
return a + 3
def odd(a):
return a % 2 == 1
list(map(add, filter(odd, items)))
> [4, 6]
A very interesting question which has an interesting answer.
The map
function returns a Map object which is iterable. map
is performing its calculation lazily so the function wouldn’t get called unless you iterate that object.
So if you do:
x = map(D.attach_item, items)
for i in x:
continue
The expected result will show up.
From the title, yes there is a difference. Now applied to my scenario: let’s consider a class Dummy
:
class Dummy:
def __init__(self):
self.attached = []
def attach_item(self, item):
self.attached.append(item)
If I use this:
D = Dummy()
items = [1, 2, 3, 4]
for item in items:
D.attach_item(item)
I indeed get D.attached = [1, 2, 3, 4]
. But if I map the function attach_item
to the items
, D.attached
remains empty.
map(D.attach_item, items)
What is it doing?
map
only creates an iterator. You should iterate through it to add items into D.attached
. Like this:
D = Dummy()
items = [1, 2, 3, 4]
list(map(D.attach_item, items))
Yep, don’t do it in your code:) But the example is just useful for understanding.
Quoting the documentation
Return an iterator that applies function to every item of iterable, yielding the results.
which means you have to collect the iterator, e.g.
list(map(D.attach_item, items))
> [None, None, None, None]
Hmmm, strange. Why None, None, …
Yes, you can convert any loop in a map statement, but it’s not always useful.
Map takes a parameter and does something with it (in most cases) an returns it, without side effects! Here’s an example:
def add(a):
return a + 3
list(map(add, items))
> [4, 5, 6, 7]
The true power comes, when you combine it with other functions like filter
def add(a):
return a + 3
def odd(a):
return a % 2 == 1
list(map(add, filter(odd, items)))
> [4, 6]
A very interesting question which has an interesting answer.
The map
function returns a Map object which is iterable. map
is performing its calculation lazily so the function wouldn’t get called unless you iterate that object.
So if you do:
x = map(D.attach_item, items)
for i in x:
continue
The expected result will show up.