[Python] Correct usage of map

Introduction

When you first touch map, you will think, "Is the definition like this?"

map(function, list)

But this is correct.

map(callable, *iterable)

I will explain this true meaning in an easy-to-understand manner while shaping map (function, list).

Add a? Mark to the definition in the middle of shaping

? map(function, list)

Freshly learned recognition

If you want to use a thing that has undergone certain processing for each element of list, use the map function. The return value is a map object, a kind of iterator. An iterator is an object that can be turned with a for statement. The map object is not a list.

>>> iterable = map(int, ["1", "2", "3", "4", "5"])
>>> for i in iterable:
...    print(i)
... 
1
2
3
4
5

Does the definition look like this?

? map(function, list)

No, the second argument actually takes an iterable (an object that can be an iterator). In other words, anything that can be turned with a ** for statement ** can be received as an argument. Of course, the iterator itself is iterable.

? map(function, iterable)

Receive an object (iterable) that can be an iterator

Don't worry too much, iterable and iterator are a little different.

Iterators can be used to extract the next element using the next function, and iterables can be converted to iterators using the iter function. For example, a list object cannot be fetched from the first element with the next function, but it can be converted to an iterator (list_iterator) with the iter function. The list_iterator can then use the next function to retrieve the next element.

a = [100, 200, 300]
# next(a) <-error!
a_iter = iter(a)
next(a_iter) #100 is taken out

There are many other iterable objects besides list. The following is an example.

tuple

Since tuple can be turned with a for statement, it can be specified as the second argument of the map function.

>>> list(map(int,  ("1", "2", "3", "4", "5"))
[1, 2, 3, 4, 5]

dict

If you turn dict with a for statement, the key will be retrieved. Therefore, if dict is specified as the second argument of the map function, each key will be used for processing.

>>> list(map(lambda k: k+k, {"a": 2, "b": 3, "c": 5, "d": 7})
['aa', 'bb', 'cc', 'dd']

If you want to retrieve both the key and the value, use dict's items method. At that time, tuple (let's say x) of (key, value) is passed to the function passed to the first argument of the map method, so when using the key, usex [0], the value. The case should be x [1].

>>> list(map(lambda x: x[0]*x[1], {"a": 2, "b": 3, "c": 5, "d": 7}.items())
['aa', 'bbb', 'ccccc', 'ddddddd']

str

str can also be turned with a for statement.

>>> "".join(map(lambda c: f'{c}"', 'Why is that'))
'Do"U"Shi"hand"Is"Yo"Mm"O"'

Generator type

Generator expressions are also iterators, but using map for them is redundant. It is better to describe everything in a generator formula.

No good


map(lambda x: 2*x, i*i for i in range(9))

Yoshi


(2*i*i for i in range(9)) 

map object

Since the map object is also an iterator, it can be specified in the second argument of the map method. However, like the generator formula, this method is redundant. (Readability may be good)

python


map(bin, map(int, ["20","19","12","25"]))

python


map(lambda x: bin(int(x)), ["20","19","12","25"])

file object

The file object created by the open function is also an iterator. If you turn it with the for statement, it will be extracted as a character string line by line.

script.txt


Thanks
Thanks
What are your hobbies?
A little LISP...
Ri...?
>>> print(*map(lambda line: f"「{line.strip()}」", open("script.txt")), sep="\n")
"Thanks"
"Thanks"
"What are your hobbies?"
"A little LISP...」
"Ri...?」

It can be applied to various other iterables.

function

? map(function, iterable)

Proprietary function

A function defined by the ** def keyword ** can also be specified as the first argument corresponding to function.

>>> def f(x):
...    a = x
...    # ...Great processing
...    # ...
...    return a
>>> list(map(f, [1,2,3,4,5,6]))
[43248956, 613134354, 6435432, 543575356, 45457623, 243543566]

Function that accepts multiple arguments

You can also specify ** a function that accepts multiple arguments ** as the first argument of map. In that case, ** iterable passed to map will increase by that amount **.

? map(Function with N arguments, iterable1, iterable2, ..., iterableN)

For example, about the following functions, list

def f(first, second, third):
   ...

iterable1 = [100, 200, 300, 400]
iterable2 = ["a", "b", "c", "d"]
iterable3 = ["A", "B", "C", "D"]

The call when using the map function as shown in the table below is shown in the table below.

map(f, iterable1, iterable2, iterable3)
Processing order iterable1 iterable2 iterable3 Call function f
0 100 "a" "A" f(100, "a", "A")
1 200 "b" "B" f(200, "b", "B")
2 300 "c" "C" f(300, "c", "C")
3 400 "d" "D" f(400, "d", "D")

Since any number of iterables are received, the second and subsequent arguments of ** map are variadic arguments **. Therefore, the correct description is as follows.

? map(function, *iterable)

Examples of actual use are the operator modules ʻadd and mul`.

ʻAdd` is a function of "+".

>>> add(2, 3)
5

mul is a function of" * ".

>>> mul(4, 5)
20

Since mul is a function ** that receives two arguments **, prepare two ** iterables ** when using the map function.

>>> from operator import mul
>>> list(map(mul, [1,2,3,4,5], [5,4,3,2,1]))
[5, 8, 9, 8, 5]

The inner product can also be described clearly.

>>> sum(map(mul, [1,2,3,4,5], [5,4,3,2,1]))
35

Not just functions

Not only ** functions can be passed as the first argument **. ** Any callable object ** is fine. ** Callable objects are those that can be called with "parentheses ()" **.

? map(callable, *iterable)

Another typical example of a function is ** class **. Since the defined ** class itself is also a callable object **, it can be specified as the first argument of map.

class Man:
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return f"Man('{self.name}')"

print(*map(Man, ["John", "Hideo", "Mitchell", "Chatarai"]))
# Man('John') Man('Hideo') Man('Mitchell') Man('Chatarai')

Of course, if you want to receive multiple arguments in the constructor, you can specify the iterable for that.

That's all there is to it.

Summary

The definition of the map function is as follows.

map(callable, *iterable)

The first argument is ** a callable object (function or class) with one or more arguments **

After the second argument, ** specify iterable objects (objects that can be iterators such as list) as many as the number of arguments required by the callable of the first argument **.

Recommended Posts

[Python] Correct usage of map
[Python] Correct usage of join
[python] Correct usage of if statement
Usage of Python locals ()
Sample usage of Python pickle
Basic usage of Python f-string
Introduction of Python
Basics of Python ①
Basics of python ①
Copy of python
Non-logical operator usage of or in python
Introduction of Python
Compare the speed of Python append and map
[Python] Class type and usage of datetime module
[Introduction to Python] Basic usage of lambda expressions
[Python] Operation of enumerate
Unification of Python environment
Copy of python preferences
Basics of Python scraping basics
Summary of pyenv usage
Basic usage of flask-classy
[python] behavior of argmax
Basic usage of Jinja2
Ruby, Python and map
the zen of Python
python decorator usage notes
Basic usage of SQLAlchemy
Installation of Python 3.3 rc1
[Python] pytest-mock Usage notes
# 4 [python] Basics of functions
Basic knowledge of Python
Sober trivia of python3
Summary of Python arguments
Basics of python: Output
Installation of matplotlib (Python 3.3.2)
Application of Python 3 vars
Various processing of Python
Python --Explanation and usage summary of the top 24 packages
[Introduction to Python] Basic usage of the library matplotlib
Super basic usage of pytest
Towards the retirement of Python2
Summary of python file operations
Summary of Python3 list operations
Using multiple versions of Python on Mac OS X (2) Usage
Python --Quick start of logging
Recommendation of binpacking library of python
Basic usage of PySimple GUI
[python] Value of function object (?)
Python standard unittest usage notes
Construction of Python local development environment Part 2 (pyenv-virtualenv, pip usage)
python * args, ** kwargs Usage notes
Automatic update of Python module
Python --Check type of values
[Python] Etymology of python function names
About the ease of Python
Static analysis of Python programs
About various encodings of Python 3
Equivalence of objects in Python
Convenient usage summary of Flask
Introduction of activities applying Python
python> Handling of 2D arrays