3
votes

In python 2, I used map to apply a function to several items, for instance, to remove all items matching a pattern:

map(os.remove,glob.glob("*.pyc"))

Of course I ignore the return code of os.remove, I just want all files to be deleted. It created a temp instance of a list for nothing, but it worked.

With Python 3, as map returns an iterator and not a list, the above code does nothing. I found a workaround, since os.remove returns None, I use any to force iteration on the full list, without creating a list (better performance)

any(map(os.remove,glob.glob("*.pyc")))

But it seems a bit hazardous, specially when applying it to methods that return something. Another way to do that with a one-liner and not create an unnecessary list?

1
Yep: for x in glob.glob("*.pyc"): os.remove(x) - vaultah
If you do want to keep the list, then I think list comprehension is the canonical way to do it. You can write map(func,items) as [func(x) for x in items] - Victor Chubukov

1 Answers

3
votes

The change from map() (and many other functions from 2.7 to 3.x) returning a generator instead of a list is a memory saving technique. For most cases, there is no performance penalty to writing out the loop more formally (it may even be preferred for readability).

I would provide an example, but @vaultah nailed it in the comments: still a one-liner:

for x in glob.glob("*.pyc"): os.remove(x)