サーチ…


構文

  • map(関数、iterable [、* additional_iterables])
  • future_builtins.map(関数、iterable [、* additional_iterables])
  • itertools.imap(function、iterable [、* additional_iterables])

パラメーター

パラメータ詳細
関数マッピングのための関数(iterablesがあるのと同じくらい多くのパラメータを取る必要があります)( 位置限定
繰り返し可能な関数は反復可能( 位置指定のみ )の各要素に適用され、
* additional_iterables iterableを参照してください。ただし、好きなだけ多く( オプション位置限定

備考

mapを使って行うことができるすべてのことは、 comprehensionsをもって行うこともできます。

list(map(abs, [-1,-2,-3]))    # [1, 2, 3]
[abs(i) for i in [-1,-2,-3]]  # [1, 2, 3]

複数のiterableがある場合は、 zipが必要です。

import operator
alist = [1,2,3]
list(map(operator.add, alist, alist))  # [2, 4, 6]
[i + j for i, j in zip(alist, alist)]  # [2, 4, 6]

リスト内包は効率的であり、多くの場合mapよりも速くなる可能性があるため、速度が重要な場合は両方のアプローチの時間をテストします。

map、itertools.imap、future_builtins.mapの基本的な使い方

マップ関数は、関数型プログラミングに使用されるPythonビルトインの中で最も単純なものです。 map()は、指定された関数を反復可能な要素の各要素に適用します。

names = ['Fred', 'Wilma', 'Barney']
Python 3.x 3.0
map(len, names)  # map in Python 3.x is a class; its instances are iterable
# Out: <map object at 0x00000198B32E2CF8>

future_builtinsモジュールには、Python 3互換mapが含まれてfuture_builtinsます。

Python 2.x 2.6
from future_builtins import map  # contains a Python 3.x compatible map()
map(len, names)                  # see below
# Out: <itertools.imap instance at 0x3eb0a20>

あるいは、Python 2ではitertools imapを使ってジェネレータを得ることができます

Python 2.x 2.3
map(len, names)   # map() returns a list
# Out: [4, 5, 6]

from itertools import imap
imap(len, names)  # itertools.imap() returns a generator
# Out: <itertools.imap at 0x405ea20>

結果を明示的にlistに変換して、Python 2とPython 3の違いを取り除くことができます:

list(map(len, names))
# Out: [4, 5, 6]

map()は、同等のリスト理解またはジェネレータ式に置き換えることができます:

[len(item) for item in names] # equivalent to Python 2.x map()
# Out: [4, 5, 6]

(len(item) for item in names) # equivalent to Python 3.x map()
# Out: <generator object <genexpr> at 0x00000195888D5FC0>

iterableの各値のマッピング

たとえば、各要素の絶対値を取ることができます。

list(map(abs, (1, -1, 2, -2, 3, -3))) # the call to `list` is unnecessary in 2.x
# Out: [1, 1, 2, 2, 3, 3]

匿名関数はリストのマッピングもサポートしています:

map(lambda x:x*2, [1, 2, 3, 4, 5])
# Out: [2, 4, 6, 8, 10]

小数点以下の値をパーセンテージに変換する:

def to_percent(num):
    return num * 100

list(map(to_percent, [0.95, 0.75, 1.01, 0.1]))
# Out: [95.0, 75.0, 101.0, 10.0]

ドルをユーロに換算する(換算レートを指定)

from functools import partial
from operator import mul

rate = 0.9  # fictitious exchange rate, 1 dollar = 0.9 euros
dollars = {'under_my_bed': 1000,
           'jeans': 45,
           'bank': 5000}

sum(map(partial(mul, rate), dollars.values()))
# Out: 5440.5

functools.partialは、関数のパラメータをlambdaを使うのではなくmapで使うか、カスタマイズされた関数を作るかのように修正する便利な方法です。

異なるiterablesの値のマッピング

例えば、複数のイテラブルの各i番目の要素の平均を計算する:

def average(*args):
    return float(sum(args)) / len(args)  # cast to float - only mandatory for python 2.x

measurement1 = [100, 111, 99, 97]
measurement2 = [102, 117, 91, 102]
measurement3 = [104, 102, 95, 101]

list(map(average, measurement1, measurement2, measurement3))
# Out: [102.0, 110.0, 95.0, 100.0]

Pythonのバージョンに応じて、複数のiterableがmap渡された場合の要件は異なります。

  • この関数は、iterableと同じ数のパラメータを取る必要があります。

    def median_of_three(a, b, c):
        return sorted((a, b, c))[1]
    
    list(map(median_of_three, measurement1, measurement2))
    

    TypeError:median_of_three()missing 1必要な位置引数: 'c'

    list(map(median_of_three, measurement1, measurement2, measurement3, measurement3))
    

    TypeError:median_of_three()は3つの位置引数を取るが、4つが与えられた

Python 2.x 2.0.1
  • map :1つのiterableがまだ完全には消費されていないが、完全に消費されたiterableからNoneを仮定する限り、マッピングは繰り返します。

    import operator
    
    measurement1 = [100, 111, 99, 97]
    measurement2 = [102, 117]
    
    # Calculate difference between elements
    list(map(operator.sub, measurement1, measurement2))
    

    TypeError: - : 'int'および 'NoneType'のサポートされていないオペランドタイプ

  • itertools.imapおよびfuture_builtins.mapつの反復可能future_builtins.mapが停止するとすぐにマッピングが停止します。

    import operator
    from itertools import imap
    
    measurement1 = [100, 111, 99, 97]
    measurement2 = [102, 117]
    
    # Calculate difference between elements
    list(imap(operator.sub, measurement1, measurement2))
    # Out: [-2, -6]
    list(imap(operator.sub, measurement2, measurement1))
    # Out: [2, 6]
    
Python 3.x 3.0.0
  • 1つの反復可能関数が停止するとすぐにマッピングは停止します。

    import operator
    
    measurement1 = [100, 111, 99, 97]
    measurement2 = [102, 117]
    
    # Calculate difference between elements
    list(map(operator.sub, measurement1, measurement2))
    # Out: [-2, -6]
    list(map(operator.sub, measurement2, measurement1))
    # Out: [2, 6]
    

マップを使った転移:関数の引数として "None"を使う(Python 2.xのみ)

from itertools import imap
from future_builtins import map as fmap # Different name to highlight differences

image = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]]

list(map(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
list(fmap(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
list(imap(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

image2 = [[1, 2, 3],
          [4, 5],
          [7, 8, 9]]
list(map(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8), (3, None, 9)]  # Fill missing values with None
list(fmap(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8)]                # ignore columns with missing values
list(imap(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8)]                # dito
Python 3.x 3.0.0
list(map(None, *image))

TypeError: 'NoneType'オブジェクトは呼び出し可能ではありません

しかし、同様の結果を得るための回避策があります:

def conv_to_list(*args):
    return list(args)

list(map(conv_to_list, *image))
# Out: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

シリーズおよびパラレルマッピング

map()はビルトイン関数です。つまり、 'import'ステートメントを使用することなくどこでも使用できます。例5を見ると、pretty print(import pprint)を使用する前にimport文を使用しなければならないことがわかります。したがって、pprintは組み込み関数ではありません

シリーズマッピング

この場合、イテラブルの各引数は、マッピング関数の引数として昇順に供給されます。これは、マッピングする反復可能性が1つしかなく、マッピング関数が単一の引数を必要とする場合に発生します。

例1

insects = ['fly', 'ant', 'beetle', 'cankerworm']
f = lambda x: x + ' is an insect'
print(list(map(f, insects))) # the function defined by f is executed on each item of the iterable insects

結果は

['fly is an insect', 'ant is an insect', 'beetle is an insect', 'cankerworm is an insect']

例2

print(list(map(len, insects))) # the len function is executed each item in the insect list

結果は

[3, 3, 6, 10]

パラレルマッピング

この場合、マッピング関数の各引数は、すべてのiterable(各iterableから1つ)から並列に引き出されます。したがって、提供されるイテラブルの数は、関数が必要とする引数の数と一致しなければなりません。

carnivores = ['lion', 'tiger', 'leopard', 'arctic fox']
herbivores = ['african buffalo', 'moose', 'okapi', 'parakeet']
omnivores = ['chicken', 'dove', 'mouse', 'pig']

def animals(w, x, y, z):
    return '{0}, {1}, {2}, and {3} ARE ALL ANIMALS'.format(w.title(), x, y, z)

例3

# Too many arguments
# observe here that map is trying to pass one item each from each of the four iterables to len. This leads len to complain that
# it is being fed too many arguments
print(list(map(len, insects, carnivores, herbivores, omnivores)))

結果は

TypeError: len() takes exactly one argument (4 given)

例4

# Too few arguments
# observe here that map is suppose to execute animal on individual elements of insects one-by-one. But animals complain when
# it only gets one argument, whereas it was expecting four.
print(list(map(animals, insects)))

結果は

TypeError: animals() missing 3 required positional arguments: 'x', 'y', and 'z'

実施例5

# here map supplies w, x, y, z with one value from across the list
import pprint
pprint.pprint(list(map(animals, insects, carnivores, herbivores, omnivores)))

結果は

 ['Fly, lion, african buffalo, and chicken ARE ALL ANIMALS',
 'Ant, tiger, moose, and dove ARE ALL ANIMALS',
 'Beetle, leopard, okapi, and mouse ARE ALL ANIMALS',
 'Cankerworm, arctic fox, parakeet, and pig ARE ALL ANIMALS']


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow