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)
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)
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 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))
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"])
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.
? map(function, iterable)
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]
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 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.
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