Python の組み込み関数 map の使い方です。
map 関数で、iterable なオブジェクトに(リストやジェネレーターなどの反復可能なオブジェクトに)、関数を適用します。
そのコード例と、実行結果を載せました。
あと、『エラーになったコード例』も書きました。
エラーになったコード例
map 関数で、エラーになったコード例です。
(Python) map(function, iterable, ...)
map()
TypeError: map() must have at least two arguments.
map(str)
TypeError: map() must have at least two arguments.
map(str, None)
TypeError: 'NoneType' object is not iterable
map(str, 100)
TypeError: 'int' object is not iterable
map(function=str, iterable=[1, 2, 3])
TypeError: map() takes no keyword arguments
datas = map(True, [1, 2, 3])
print(list(datas)) # TypeError
TypeError: 'bool' object is not callable
datas = map('abc', [1, 2, 3])
print(list(datas)) # TypeError
TypeError: 'str' object is not callable
map 関数の戻り値は『イテレーター』でした
map 関数の戻り値は、リストではなくて、『map オブジェクト』という名前の iterator になっていました。
(Python) map(function, iterable, ...)
(Python) リストからビューおよびイテレータへ(map 関数はイテレータを返します)
(Python) iterable イテラブル(反復可能オブジェクト)
(Python) iterator イテレーター(データの流れを表現するオブジェクト)
map(lambda x: x * 100, [1, 2, 3])
<map object at 0x0000000000000000>
なので、map 関数から『結果を取り出すとき』は、戻り値を『tuple 関数 や list 関数』に渡したり、『next 関数や for 文』に渡したらできました。
datas = map(lambda x: x * 100, [1, 2, 3])
print(tuple(datas))
(100, 200, 300)
(Python) class list([iterable])
datas = map(lambda x: x * 100, [1, 2, 3])
print(list(datas))
[100, 200, 300]
(Python) next(iterator[, default])
datas = map(lambda x: x * 100, [1, 2, 3])
print(next(datas))
print(next(datas))
print(next(datas))
100
200
300
datas = map(lambda x: x * 100, [1, 2, 3])
for data in datas:
print(data)
100
200
300
tuple を渡した結果
map 関数に、tuple を渡した結果です。
(Python) map(function, iterable, ...)
(Python) functools.partial(func, /, *args, **keywords)
(Python) class int(x, base=10)
datas = map(str, ())
print(tuple(datas))
()
datas = map(str, (True, False, None, 255))
print(tuple(datas))
('True', 'False', 'None', '255')
src_datas = ('00', '01', '10', '11')
datas = map(lambda x: int(x, base=2), src_datas)
print(tuple(datas))
(0, 1, 2, 3)
from functools import partial
src_datas = ('00', '01', '10', '11')
datas = map(partial(int, base=2), src_datas)
print(tuple(datas))
(0, 1, 2, 3)
datas = map(lambda x: 500 * x, (1, 2, 3, 4))
print(tuple(datas))
(500, 1000, 1500, 2000)
from functools import partial
from operator import mul
# mul: Multiplication (掛け算、マルチプリケーション)
datas = map(partial(mul, 500), (1, 2, 3, 4))
print(tuple(datas))
(500, 1000, 1500, 2000)
list を渡した結果
map 関数に、list を渡した結果です。
(Python) map(function, iterable, ...)
(Python) class list([iterable])
(Python) functools.partial(func, /, *args, **keywords)
(Python) class int(x, base=10)
datas = map(str, [])
print(list(datas))
[]
datas = map(str, [True, False, None, 255])
print(list(datas))
['True', 'False', 'None', '255']
src_datas = ['00', '01', '10', '11']
datas = map(lambda x: int(x, base=2), src_datas)
print(list(datas))
[0, 1, 2, 3]
from functools import partial
src_datas = ['00', '01', '10', '11']
datas = map(partial(int, base=2), src_datas)
print(list(datas))
[0, 1, 2, 3]
datas = map(lambda x: 500 * x, [1, 2, 3, 4])
print(list(datas))
[500, 1000, 1500, 2000]
from functools import partial
from operator import mul
# mul: Multiplication (掛け算、マルチプリケーション)
datas = map(partial(mul, 500), [1, 2, 3, 4])
print(list(datas))
[500, 1000, 1500, 2000]
generator オブジェクトを渡した結果
map 関数に、generator オブジェクトを渡した結果です。
(Python) map(function, iterable, ...)
(Python) ジェネレータ式(Python チュートリアル)
(Python) ジェネレータ式とリスト内包表記(Python 言語リファレンス)
(Python) ジェネレータ式 (generator expression)(Python 言語リファレンス)
(Python) ジェネレータ (generator)(Python チュートリアル)
(Python) functools.partial(func, /, *args, **keywords)
(Python) class int(x, base=10)
from functools import partial
src_datas = (x for x in ['00', '01', '10', '11'])
print(src_datas)
datas = map(partial(int, base=2), src_datas)
print(list(datas))
<generator object <genexpr> at 0x0000000000000000>
[0, 1, 2, 3]
src_datas = (x for x in ['00', '01', '10', '11'])
print(src_datas)
datas = map(lambda x: int(x, base=2), src_datas)
print(list(datas))
<generator object <genexpr> at 0x0000000000000000>
[0, 1, 2, 3]
src_datas = (x for x in ['00', '01', '10', '11'])
print(src_datas)
datas = map(lambda x: int(x, base=8), src_datas)
print(list(datas))
<generator object <genexpr> at 0x0000000000000000>
[0, 1, 8, 9]
src_datas = (x for x in ['00', '01', '10', '11'])
print(src_datas)
datas = map(lambda x: int(x, base=10), src_datas)
print(list(datas))
<generator object <genexpr> at 0x0000000000000000>
[0, 1, 10, 11]
src_datas = (x for x in ['00', '01', '10', '11'])
print(src_datas)
datas = map(lambda x: int(x, base=16), src_datas)
print(list(datas))
<generator object <genexpr> at 0x0000000000000000>
[0, 1, 16, 17]
def generate_datas():
for x in ['00', '01', '10', '11']:
yield x
print(generate_datas)
src_datas = generate_datas()
print(src_datas)
datas = map(lambda x: int(x, base=16), src_datas)
print(list(datas))
<function generate_datas at 0x0000000000000000>
<generator object generate_datas at 0x0000000000000000>
[0, 1, 16, 17]
iterator オブジェクトを渡した結果
map 関数に、iterator オブジェクトを渡した結果です。
(Python) map(function, iterable, ...)
(Python) iter(object[, sentinel])
(Python) イテレータ (iterator)(Python チュートリアル)
(Python) イテレータ (iterator)(関数型プログラミング HOWTO)
(Python) class int(x, base=10)
(Python) functools.partial(func, /, *args, **keywords)
from functools import partial
src_datas = iter(['00', '01', '10', '11'])
print(src_datas)
datas = map(partial(int, base=2), src_datas)
print(list(datas))
<list_iterator object at 0x0000000000000000>
[0, 1, 2, 3]
src_datas = iter(['00', '01', '10', '11'])
print(src_datas)
datas = map(lambda x: int(x, base=2), src_datas)
print(list(datas))
<list_iterator object at 0x0000000000000000>
[0, 1, 2, 3]
src_datas = iter(['00', '01', '10', '11'])
print(src_datas)
datas = map(lambda x: int(x, base=8), src_datas)
print(list(datas))
<list_iterator object at 0x0000000000000000>
[0, 1, 8, 9]
src_datas = iter(['00', '01', '10', '11'])
print(src_datas)
datas = map(lambda x: int(x, base=10), src_datas)
print(list(datas))
<list_iterator object at 0x0000000000000000>
[0, 1, 10, 11]
src_datas = iter(['00', '01', '10', '11'])
print(src_datas)
datas = map(lambda x: int(x, base=16), src_datas)
print(list(datas))
<list_iterator object at 0x0000000000000000>
[0, 1, 16, 17]
複数の条件を設定した結果
map 関数に『複数の条件』を指定した結果です。
複数の条件は、自作関数で実現することができました。
自作関数は、『lambda 式』でも、普通の『関数定義』で作ったものでも、渡すことができました。
(Python) map(function, iterable, ...)
(Python) ラムダ式(Python チュートリアル)
(Python) ラムダ (lambda)(Python 言語リファレンス)
(Python) 関数を定義する(Python チュートリアル)
(Python) 関数定義(Python 言語リファレンス)
(Python) isinstance(object, classinfo)
試しに、x[0] が『文字列 (str)』で、x[1] が『None ではないもの』を選んで、大文字に変換してみました。
src_datas = [['abc', True], ['xyz', None], [None, True]]
func = lambda x: [x[0].upper(), x[1]] if isinstance(x[0], str) and (x[1] is not None) else x
datas = map(func, src_datas)
print(list(datas))
[['ABC', True], ['xyz', None], [None, True]]
src_datas = [['abc', True], ['xyz', None], [None, True]]
def func(x):
if isinstance(x[0], str):
if x[1] is not None:
return [x[0].upper(), x[1]]
return x
datas = map(func, src_datas)
print(list(datas))
[['ABC', True], ['xyz', None], [None, True]]
『map 関数』と『内包表記』は、どちらが良いのか?
自分は、『内包表記』のほうが、簡単で分かりやすくて良かったです。
map 関数と同じような処理は、『リスト内包表記 []
』や『ジェネレータ式 ()
』で書くことができました。
(Python) 組み込み関数 (built-in function) のところにも、『Python のビルトイン関数 map() と filter() は、機能がジェネレータ式と重複しています』という説明がありました。
結果をリストで受け取るなら『角カッコのリスト内包表記 []
』が便利でしたし、遅延評価にするなら『丸カッコのジェネレータ式 ()
』が便利でした。
(Python) ジェネレータ式とリスト内包表記(Python 言語リファレンス)
(Python) ジェネレータ式 (generator expression)(Python 言語リファレンス)
(Python) generator expression(ジェネレータ式)(用語集)
(Python) list comprehension(リスト内包表記)(用語集)
内包表記などは、map 関数とちがって、『lambda 式なし(自作関数なし)』で色々な関数を適用することができましたし、for 文も見えていて直感的でした。
さらに、リストのリストであっても、lambda 式を使うことなく、リストの要素を参照することができて、便利でした。
そういうわけで、map 関数の使用は、機会があるたびに検討はしたものの、結局、内包表記やジェネレータ式を使うに至りました。
map 関数よりも、内包表記などのほうが、機能的にも使いやすさ的にも、メリットが大きかったです。
以上です。